From 94413e51b0558f0b55137328d51ce8c26dd358a0 Mon Sep 17 00:00:00 2001 From: Gianni Tedesco Date: Thu, 12 Aug 2010 18:55:16 +0100 Subject: [PATCH] xl: Implement per-API-call garbage-collection lifetime Currently scratch variables allocated by libxl have the same lifetime as the context. While this is suitable for one off invocations of xl. It is not so great for a daemon process linking to libxl. In that case there will be prolific leakage of heap memory. My proposed solution involves create a new libxl_gc structure, which contains a pointer to an owning context as well as the garbage collection data. Top-level library functions which expect to do a lot of scratch allocations put gc struct on the stack and initialize it with a macro. Before returning they then call libxl_free_all on this struct. This means that static helper functions called by such functions will usually take a gc instead of a ctx as a first parameter. The patch touches almost every code-path so a close review and testing would be much appreciated. I have tested with valgrind all of the parts I could which looked non-straightforward. Suffice to say that it seems crash-free even if we have exposed a few real memory leaks. These are for cases where we return eg. block list to an xl caller but there is no appropriate block_list_free() function to call. Ian Campbells work in this area should sew up all these loose ends. Signed-off-by: Gianni Tedesco committer: Stefano Stabellini --- tools/libxl/libxl.c | 1087 +++++++++++++++++++------------- tools/libxl/libxl.h | 6 +- tools/libxl/libxl_bootloader.c | 80 ++- tools/libxl/libxl_device.c | 133 ++-- tools/libxl/libxl_dom.c | 226 ++++--- tools/libxl/libxl_exec.c | 10 +- tools/libxl/libxl_internal.c | 65 +- tools/libxl/libxl_internal.h | 54 +- tools/libxl/libxl_pci.c | 347 +++++----- tools/libxl/libxl_utils.c | 197 +++--- tools/libxl/libxl_xshelp.c | 28 +- tools/libxl/xl_cmdimpl.c | 5 +- 12 files changed, 1291 insertions(+), 947 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index cdff9f3b63..a29cabd54d 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -45,17 +45,12 @@ int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger *lg) return ERROR_VERSION; memset(ctx, 0, sizeof(libxl_ctx)); ctx->lg = lg; - ctx->alloc_maxsize = 256; - ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *)); - if (!ctx->alloc_ptrs) - return ERROR_NOMEM; memset(&ctx->version_info, 0, sizeof(libxl_version_info)); ctx->xch = xc_interface_open(lg,lg,0); if (!ctx->xch) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, "cannot open libxc handle"); - free(ctx->alloc_ptrs); return ERROR_FAIL; } @@ -64,7 +59,6 @@ int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger *lg) XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, "cannot connect to xenstore"); xc_interface_close(ctx->xch); - free(ctx->alloc_ptrs); return ERROR_FAIL; } return 0; @@ -73,8 +67,6 @@ int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger *lg) static void do_free_version_info(libxl_version_info *info); int libxl_ctx_free(libxl_ctx *ctx) { - libxl_free_all(ctx); - free(ctx->alloc_ptrs); xc_interface_close(ctx->xch); do_free_version_info(&ctx->version_info); if (ctx->xsh) xs_daemon_close(ctx->xsh); @@ -86,6 +78,7 @@ int libxl_ctx_free(libxl_ctx *ctx) int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int flags, ret, i, rc; char *uuid_string; char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"}; @@ -98,7 +91,10 @@ int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, xen_domain_handle_t handle; uuid_string = libxl_uuid2string(ctx, info->uuid); - if (!uuid_string) return ERROR_NOMEM; + if (!uuid_string) { + libxl_free_all(&gc); + return ERROR_NOMEM; + } flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; @@ -111,22 +107,27 @@ int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid); if (ret < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain creation fail"); + libxl_free_all(&gc); return ERROR_FAIL; } ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid); if (ret < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain move fail"); + libxl_free_all(&gc); return ERROR_FAIL; } - dom_path = libxl_xs_get_dompath(ctx, *domid); - if (!dom_path) + dom_path = libxl_xs_get_dompath(&gc, *domid); + if (!dom_path) { + libxl_free_all(&gc); return ERROR_FAIL; + } - vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string); + vm_path = libxl_sprintf(&gc, "/vm/%s", uuid_string); if (!vm_path) { XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate create paths"); + libxl_free_all(&gc); return ERROR_FAIL; } @@ -147,42 +148,47 @@ retry_transaction: xs_mkdir(ctx->xsh, t, vm_path); xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); rc = libxl_domain_rename(ctx, *domid, 0, info->name, t); - if (rc) return rc; + if (rc) { + libxl_free_all(&gc); + return rc; + } for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { - char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]); + char *path = libxl_sprintf(&gc, "%s/%s", dom_path, rw_paths[i]); xs_mkdir(ctx->xsh, t, path); xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); - libxl_free(ctx, path); } for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { - char *path = libxl_sprintf(ctx, "%s/%s", dom_path, ro_paths[i]); + char *path = libxl_sprintf(&gc, "%s/%s", dom_path, ro_paths[i]); xs_mkdir(ctx->xsh, t, path); xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); - libxl_free(ctx, path); } - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, strlen(info->name)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name)); if (info->poolname) - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); - libxl_xs_writev(ctx, t, dom_path, info->xsdata); - libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), info->platformdata); + libxl_xs_writev(&gc, t, dom_path, info->xsdata); + libxl_xs_writev(&gc, t, libxl_sprintf(&gc, "%s/platform", dom_path), info->platformdata); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; + + libxl_free_all(&gc); return 0; } int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid, const char *old_name, const char *new_name, - xs_transaction_t trans) { + xs_transaction_t trans) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path = 0; const char *name_path; char *got_old_name; @@ -190,10 +196,10 @@ int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid, xs_transaction_t our_trans = 0; int rc; - dom_path = libxl_xs_get_dompath(ctx, domid); + dom_path = libxl_xs_get_dompath(&gc, domid); if (!dom_path) goto x_nomem; - name_path= libxl_sprintf(ctx, "%s/name", dom_path); + name_path= libxl_sprintf(&gc, "%s/name", dom_path); if (!name_path) goto x_nomem; retry_transaction: @@ -250,8 +256,8 @@ int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid, rc = 0; x_rc: - if (dom_path) libxl_free(ctx, dom_path); if (our_trans) xs_transaction_end(ctx->xsh, our_trans, 1); + libxl_free_all(&gc); return rc; x_fail: rc = ERROR_FAIL; goto x_rc; @@ -260,38 +266,42 @@ int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid, int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char **vments = NULL, **localents = NULL; struct timeval start_time; int i, ret; ret = build_pre(ctx, domid, info, state); - if (ret) goto out; + if (ret) + goto out; gettimeofday(&start_time, NULL); if (info->hvm) { ret = build_hvm(ctx, domid, info, state); - if (ret) goto out; + if (ret) + goto out; - vments = libxl_calloc(ctx, 7, sizeof(char *)); + vments = libxl_calloc(&gc, 7, sizeof(char *)); vments[0] = "rtc/timeoffset"; vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; vments[2] = "image/ostype"; vments[3] = "hvm"; vments[4] = "start_time"; - vments[5] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + vments[5] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); } else { ret = build_pv(ctx, domid, info, state); - if (ret) goto out; + if (ret) + goto out; - vments = libxl_calloc(ctx, 11, sizeof(char *)); + vments = libxl_calloc(&gc, 11, sizeof(char *)); i = 0; vments[i++] = "image/ostype"; vments[i++] = "linux"; vments[i++] = "image/kernel"; vments[i++] = (char*) info->kernel.path; vments[i++] = "start_time"; - vments[i++] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + vments[i++] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); if (info->u.pv.ramdisk.path) { vments[i++] = "image/ramdisk"; vments[i++] = (char*) info->u.pv.ramdisk.path; @@ -307,6 +317,7 @@ out: if (!info->hvm) libxl_file_reference_unmap(ctx, &info->u.pv.ramdisk); + libxl_free_all(&gc); return ret; } @@ -314,35 +325,38 @@ int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, int fd, libxl_domain_build_state *state, libxl_device_model_info *dm_info) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char **vments = NULL, **localents = NULL; struct timeval start_time; int i, ret, esave, flags; ret = build_pre(ctx, domid, info, state); - if (ret) goto out; + if (ret) + goto out; ret = restore_common(ctx, domid, info, state, fd); - if (ret) goto out; + if (ret) + goto out; gettimeofday(&start_time, NULL); if (info->hvm) { - vments = libxl_calloc(ctx, 7, sizeof(char *)); + vments = libxl_calloc(&gc, 7, sizeof(char *)); vments[0] = "rtc/timeoffset"; vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; vments[2] = "image/ostype"; vments[3] = "hvm"; vments[4] = "start_time"; - vments[5] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + vments[5] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); } else { - vments = libxl_calloc(ctx, 11, sizeof(char *)); + vments = libxl_calloc(&gc, 11, sizeof(char *)); i = 0; vments[i++] = "image/ostype"; vments[i++] = "linux"; vments[i++] = "image/kernel"; vments[i++] = (char*) info->kernel.path; vments[i++] = "start_time"; - vments[i++] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + vments[i++] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); if (info->u.pv.ramdisk.path) { vments[i++] = "image/ramdisk"; vments[i++] = (char*) info->u.pv.ramdisk.path; @@ -353,7 +367,8 @@ int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info, } } ret = build_post(ctx, domid, info, state, vments, localents); - if (ret) goto out; + if (ret) + goto out; dm_info->saved_state = NULL; if (info->hvm) { @@ -380,28 +395,36 @@ out: } errno = esave; + libxl_free_all(&gc); return ret; } int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); + int rc = 0; + if (is_hvm(ctx, domid)) { XL_LOG(ctx, XL_LOG_DEBUG, "Called domain_resume on " "non-cooperative hvm domain %u", domid); - return ERROR_NI; + rc = ERROR_NI; + goto out; } if (xc_domain_resume(ctx->xch, domid, 1)) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_domain_resume failed for domain %u", domid); - return ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } if (!xs_resume_domain(ctx->xsh, domid)) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_resume_domain failed for domain %u", domid); - return ERROR_FAIL; + rc = ERROR_FAIL; } +out: + libxl_free_all(&gc); return 0; } @@ -414,6 +437,7 @@ int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid) int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, libxl_domain_create_info *info, const char *name_suffix, libxl_uuid new_uuid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); struct xs_permissions roperm[2]; xs_transaction_t t; char *preserved_name; @@ -423,17 +447,29 @@ int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, int rc; - preserved_name = libxl_sprintf(ctx, "%s%s", info->name, name_suffix); - if (!preserved_name) return ERROR_NOMEM; + preserved_name = libxl_sprintf(&gc, "%s%s", info->name, name_suffix); + if (!preserved_name) { + libxl_free_all(&gc); + return ERROR_NOMEM; + } uuid_string = libxl_uuid2string(ctx, new_uuid); - if (!uuid_string) return ERROR_NOMEM; + if (!uuid_string) { + libxl_free_all(&gc); + return ERROR_NOMEM; + } - dom_path = libxl_xs_get_dompath(ctx, domid); - if (!dom_path) return ERROR_FAIL; + dom_path = libxl_xs_get_dompath(&gc, domid); + if (!dom_path) { + libxl_free_all(&gc); + return ERROR_FAIL; + } - vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string); - if (!vm_path) return ERROR_FAIL; + vm_path = libxl_sprintf(&gc, "/vm/%s", uuid_string); + if (!vm_path) { + libxl_free_all(&gc); + return ERROR_FAIL; + } roperm[0].id = 0; roperm[0].perms = XS_PERM_NONE; @@ -447,16 +483,17 @@ int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, xs_mkdir(ctx->xsh, t, vm_path); xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); rc = libxl_domain_rename(ctx, domid, info->name, preserved_name, t); if (rc) return rc; - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; + libxl_free_all(&gc); return 0; } @@ -586,11 +623,12 @@ int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info, int hvm = is_hvm(ctx, domid); int live = info != NULL && info->flags & XL_SUSPEND_LIVE; int debug = info != NULL && info->flags & XL_SUSPEND_DEBUG; + int rc = 0; core_suspend(ctx, domid, fd, hvm, live, debug); if (hvm) - return save_device_model(ctx, domid, fd); - return 0; + rc = save_device_model(ctx, domid, fd); + return rc; } int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid) @@ -619,24 +657,26 @@ int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid, int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path; char *state; - int ret; + int ret, rc = 0; if (is_hvm(ctx, domid)) { - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); - state = libxl_xs_read(ctx, XBT_NULL, path); + path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d/state", domid); + state = libxl_xs_read(&gc, XBT_NULL, path); if (state != NULL && !strcmp(state, "paused")) { - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "continue"); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/0/device-model/%d/command", domid), "continue"); libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL); } } ret = xc_domain_unpause(ctx->xch, domid); if (ret<0) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unpausing domain %d", domid); - return ERROR_FAIL; + rc = ERROR_FAIL; } - return 0; + libxl_free_all(&gc); + return rc; } static char *req_table[] = { @@ -649,17 +689,22 @@ static char *req_table[] = { int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid, int req) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *shutdown_path; char *dom_path; - if (req > ARRAY_SIZE(req_table)) + if (req > ARRAY_SIZE(req_table)) { + libxl_free_all(&gc); return ERROR_INVAL; + } - dom_path = libxl_xs_get_dompath(ctx, domid); - if (!dom_path) + dom_path = libxl_xs_get_dompath(&gc, domid); + if (!dom_path) { + libxl_free_all(&gc); return ERROR_FAIL; + } - shutdown_path = libxl_sprintf(ctx, "%s/control/shutdown", dom_path); + shutdown_path = libxl_sprintf(&gc, "%s/control/shutdown", dom_path); xs_write(ctx->xsh, XBT_NULL, shutdown_path, req_table[req], strlen(req_table[req])); if (is_hvm(ctx,domid)) { @@ -684,6 +729,7 @@ int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid, int req) } } } + libxl_free_all(&gc); return 0; } @@ -705,7 +751,8 @@ int libxl_wait_for_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_waiter *wa int libxl_wait_for_disk_ejects(libxl_ctx *ctx, uint32_t guest_domid, libxl_device_disk *disks, int num_disks, libxl_waiter *waiter) { - int i; + libxl_gc gc = LIBXL_INIT_GC(ctx); + int i, rc = -1; uint32_t domid = libxl_get_stubdom_id(ctx, guest_domid); if (!domid) @@ -713,14 +760,17 @@ int libxl_wait_for_disk_ejects(libxl_ctx *ctx, uint32_t guest_domid, libxl_devic for (i = 0; i < num_disks; i++) { if (asprintf(&(waiter[i].path), "%s/device/vbd/%d/eject", - libxl_xs_get_dompath(ctx, domid), + libxl_xs_get_dompath(&gc, domid), device_disk_dev_number(disks[i].virtpath)) < 0) - return -1; + goto out; if (asprintf(&(waiter[i].token), "%d", LIBXL_EVENT_DISK_EJECT) < 0) - return -1; + goto out; xs_watch(ctx->xsh, waiter->path, waiter->token); } - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_get_event(libxl_ctx *ctx, libxl_event *event) @@ -773,49 +823,56 @@ int libxl_event_get_domain_death_info(libxl_ctx *ctx, uint32_t domid, libxl_even int libxl_event_get_disk_eject_info(libxl_ctx *ctx, uint32_t domid, libxl_event *event, libxl_device_disk *disk) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path; char *backend; char *value; - value = libxl_xs_read(ctx, XBT_NULL, event->path); + value = libxl_xs_read(&gc, XBT_NULL, event->path); - if (!value || strcmp(value, "eject")) + if (!value || strcmp(value, "eject")) { + libxl_free_all(&gc); return 0; + } path = strdup(event->path); path[strlen(path) - 6] = '\0'; - backend = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", path)); + backend = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", path)); disk->backend_domid = 0; disk->domid = domid; disk->physpath = NULL; disk->phystype = 0; /* this value is returned to the user: do not free right away */ - disk->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev", backend)); + disk->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev", backend)); disk->unpluggable = 1; disk->readwrite = 0; disk->is_cdrom = 1; free(path); + libxl_free_all(&gc); return 1; } static int libxl_destroy_device_model(libxl_ctx *ctx, uint32_t domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *pid; int ret; - pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid)); + pid = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid)); if (!pid) { int stubdomid = libxl_get_stubdom_id(ctx, domid); if (!stubdomid) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't find device model's pid"); - return ERROR_INVAL; + ret = ERROR_INVAL; + goto out; } XL_LOG(ctx, XL_LOG_ERROR, "Device model is a stubdom, domid=%d\n", stubdomid); - return libxl_domain_destroy(ctx, stubdomid, 0); + ret = libxl_domain_destroy(ctx, stubdomid, 0); + goto out; } - xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", domid)); + xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, "/local/domain/0/device-model/%d", domid)); ret = kill(atoi(pid), SIGHUP); if (ret < 0 && errno == ESRCH) { @@ -828,11 +885,14 @@ static int libxl_destroy_device_model(libxl_ctx *ctx, uint32_t domid) XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to kill Device Model [%d]", atoi(pid)); } +out: + libxl_free_all(&gc); return ret; } int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path; char *vm_path; int rc, dm_present; @@ -841,20 +901,21 @@ int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force) dm_present = 1; } else { char *pid; - pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid)); + pid = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid)); dm_present = (pid != NULL); - libxl_free(ctx, pid); } - dom_path = libxl_xs_get_dompath(ctx, domid); - if (!dom_path) - return ERROR_FAIL; + dom_path = libxl_xs_get_dompath(&gc, domid); + if (!dom_path) { + rc = ERROR_FAIL; + goto out; + } if (libxl_device_pci_shutdown(ctx, domid) < 0) XL_LOG(ctx, XL_LOG_ERROR, "pci shutdown failed for domid %d", domid); if (dm_present) { xs_write(ctx->xsh, XBT_NULL, - libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), + libxl_sprintf(&gc, "/local/domain/0/device-model/%d/command", domid), "shutdown", strlen("shutdown")); } rc = xc_domain_pause(ctx->xch, domid); @@ -868,7 +929,7 @@ int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force) if (libxl_devices_destroy(ctx, domid, force) < 0) XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d", domid); - vm_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vm", dom_path)); + vm_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/vm", dom_path)); if (vm_path) if (!xs_rm(ctx->xsh, XBT_NULL, vm_path)) XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", vm_path); @@ -881,17 +942,24 @@ int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force) rc = xc_domain_destroy(ctx->xch, domid); if (rc < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for %d", domid); - return ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } + rc = 0; +out: + libxl_free_all(&gc); return 0; } int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num) { - char *p = libxl_sprintf(ctx, "%s/xenconsole", libxl_private_bindir_path()); - char *domid_s = libxl_sprintf(ctx, "%d", domid); - char *cons_num_s = libxl_sprintf(ctx, "%d", cons_num); - return execl(p, p, domid_s, "--num", cons_num_s, (void *)NULL) == 0 ? 0 : ERROR_FAIL; + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *p = libxl_sprintf(&gc, "%s/xenconsole", libxl_private_bindir_path()); + char *domid_s = libxl_sprintf(&gc, "%d", domid); + char *cons_num_s = libxl_sprintf(&gc, "%d", cons_num); + execl(p, p, domid_s, "--num", cons_num_s, (void *)NULL); + libxl_free_all(&gc); + return ERROR_FAIL; } int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm) @@ -905,6 +973,7 @@ int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm) int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass) { + libxl_gc gc = LIBXL_INIT_GC(ctx); const char *vnc_port, *vfb_back; const char *vnc_listen = NULL, *vnc_pass = NULL; int port = 0, autopass_fd = -1; @@ -915,22 +984,22 @@ int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass) NULL, }; - vnc_port = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, + vnc_port = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "/local/domain/%d/console/vnc-port", domid)); if ( vnc_port ) port = atoi(vnc_port) - 5900; - vfb_back = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, + vfb_back = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "/local/domain/%d/device/vfb/0/backend", domid)); if ( vfb_back ) { - vnc_listen = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, + vnc_listen = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "/local/domain/%d/console/vnc-listen", domid)); if ( autopass ) - vnc_pass = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, + vnc_pass = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "/local/domain/%d/console/vnc-pass", domid)); } @@ -940,7 +1009,7 @@ int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass) if ( (vnc_bin = getenv("VNCVIEWER")) ) args[0] = vnc_bin; - args[1] = libxl_sprintf(ctx, "%s:%d", vnc_listen, port); + args[1] = libxl_sprintf(&gc, "%s:%d", vnc_listen, port); if ( vnc_pass ) { char tmpname[] = "/tmp/vncautopass.XXXXXX"; @@ -962,11 +1031,12 @@ int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass) } skip_autopass: + libxl_free_all(&gc); libxl_exec(autopass_fd, -1, -1, args[0], args); return 0; } -static char ** libxl_build_device_model_args_old(libxl_ctx *ctx, +static char ** libxl_build_device_model_args_old(libxl_gc *gc, libxl_device_model_info *info, libxl_device_nic *vifs, int num_vifs) @@ -974,13 +1044,14 @@ static char ** libxl_build_device_model_args_old(libxl_ctx *ctx, int num = 0, i; flexarray_t *dm_args; dm_args = flexarray_make(16, 1); + if (!dm_args) return NULL; flexarray_set(dm_args, num++, "qemu-dm"); flexarray_set(dm_args, num++, "-d"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->domid)); if (info->dom_name) { flexarray_set(dm_args, num++, "-domain-name"); @@ -992,18 +1063,18 @@ static char ** libxl_build_device_model_args_old(libxl_ctx *ctx, if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) { flexarray_set( dm_args, num++, - libxl_sprintf(ctx, "%s:%d%s", + libxl_sprintf(gc, "%s:%d%s", info->vnclisten, info->vncdisplay, info->vncpasswd ? ",password" : "")); } else { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:%d", info->vncdisplay)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "127.0.0.1:%d", info->vncdisplay)); } } else if (info->vnclisten) { if (strchr(info->vnclisten, ':') != NULL) { flexarray_set(dm_args, num++, info->vnclisten); } else { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:0", info->vnclisten)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%s:0", info->vnclisten)); } } else { flexarray_set(dm_args, num++, "127.0.0.1:0"); @@ -1034,7 +1105,7 @@ static char ** libxl_build_device_model_args_old(libxl_ctx *ctx, if (info->videoram) { flexarray_set(dm_args, num++, "-videoram"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->videoram)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->videoram)); } if (info->stdvga) { flexarray_set(dm_args, num++, "-std-vga"); @@ -1060,24 +1131,24 @@ static char ** libxl_build_device_model_args_old(libxl_ctx *ctx, } if (info->vcpus > 1) { flexarray_set(dm_args, num++, "-vcpus"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->vcpus)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->vcpus)); } if (info->vcpu_avail) { flexarray_set(dm_args, num++, "-vcpu_avail"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "0x%x", info->vcpu_avail)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "0x%x", info->vcpu_avail)); } for (i = 0; i < num_vifs; i++) { if (vifs[i].nictype == NICTYPE_IOEMU) { - char *smac = libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + char *smac = libxl_sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x", vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]); if (!vifs[i].ifname) - vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid); + vifs[i].ifname = libxl_sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid); flexarray_set(dm_args, num++, "-net"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", + flexarray_set(dm_args, num++, libxl_sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s", vifs[i].devid, smac, vifs[i].model)); flexarray_set(dm_args, num++, "-net"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s,script=no", + flexarray_set(dm_args, num++, libxl_sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no", vifs[i].devid, vifs[i].ifname, vifs[i].bridge)); ioemu_vifs++; } @@ -1103,7 +1174,7 @@ static char ** libxl_build_device_model_args_old(libxl_ctx *ctx, return (char **) flexarray_contents(dm_args); } -static char ** libxl_build_device_model_args_new(libxl_ctx *ctx, +static char ** libxl_build_device_model_args_new(libxl_gc *gc, libxl_device_model_info *info, libxl_device_nic *vifs, int num_vifs) @@ -1120,7 +1191,7 @@ static char ** libxl_build_device_model_args_new(libxl_ctx *ctx, flexarray_set(dm_args, num++, "qemu-system-xen"); flexarray_set(dm_args, num++, "-xen-domid"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->domid)); if (info->dom_name) { flexarray_set(dm_args, num++, "-name"); @@ -1143,11 +1214,11 @@ static char ** libxl_build_device_model_args_new(libxl_ctx *ctx, if (strchr(listen, ':') != NULL) flexarray_set(dm_args, num++, - libxl_sprintf(ctx, "%s%s", listen, + libxl_sprintf(gc, "%s%s", listen, info->vncunused ? ",to=99" : "")); else flexarray_set(dm_args, num++, - libxl_sprintf(ctx, "%s:%d%s", listen, display, + libxl_sprintf(gc, "%s:%d%s", listen, display, info->vncunused ? ",to=99" : "")); } if (info->sdl) { @@ -1174,7 +1245,7 @@ static char ** libxl_build_device_model_args_new(libxl_ctx *ctx, if (info->boot) { flexarray_set(dm_args, num++, "-boot"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "order=%s", info->boot)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "order=%s", info->boot)); } if (info->usb || info->usbdevice) { flexarray_set(dm_args, num++, "-usb"); @@ -1193,22 +1264,22 @@ static char ** libxl_build_device_model_args_new(libxl_ctx *ctx, if (info->vcpus > 1) { flexarray_set(dm_args, num++, "-smp"); if (info->vcpu_avail) - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail)); else - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->vcpus)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->vcpus)); } for (i = 0; i < num_vifs; i++) { if (vifs[i].nictype == NICTYPE_IOEMU) { - char *smac = libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + char *smac = libxl_sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x", vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]); if (!vifs[i].ifname) - vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid); + vifs[i].ifname = libxl_sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid); flexarray_set(dm_args, num++, "-net"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", + flexarray_set(dm_args, num++, libxl_sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s", vifs[i].devid, smac, vifs[i].model)); flexarray_set(dm_args, num++, "-net"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,script=no", + flexarray_set(dm_args, num++, libxl_sprintf(gc, "tap,vlan=%d,ifname=%s,script=no", vifs[i].devid, vifs[i].ifname)); ioemu_vifs++; } @@ -1231,34 +1302,36 @@ static char ** libxl_build_device_model_args_new(libxl_ctx *ctx, else flexarray_set(dm_args, num++, "xenfv"); - disks = libxl_device_disk_list(ctx, info->domid, &nb); + disks = libxl_device_disk_list(libxl_gc_owner(gc), info->domid, &nb); for (; nb > 0; --nb, ++disks) { if ( disks->is_cdrom ) { flexarray_set(dm_args, num++, "-cdrom"); flexarray_set(dm_args, num++, disks->physpath); }else{ - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-%s", disks->virtpath)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "-%s", disks->virtpath)); flexarray_set(dm_args, num++, disks->physpath); } } + free(disks); flexarray_set(dm_args, num++, NULL); return (char **) flexarray_contents(dm_args); } -static char ** libxl_build_device_model_args(libxl_ctx *ctx, +static char ** libxl_build_device_model_args(libxl_gc *gc, libxl_device_model_info *info, libxl_device_nic *vifs, int num_vifs) { + libxl_ctx *ctx = libxl_gc_owner(gc); int new_qemu; new_qemu = libxl_check_device_model_version(ctx, info->device_model); if (new_qemu == 1) { - return libxl_build_device_model_args_new(ctx, info, vifs, num_vifs); + return libxl_build_device_model_args_new(gc, info, vifs, num_vifs); } else { - return libxl_build_device_model_args_old(ctx, info, vifs, num_vifs); + return libxl_build_device_model_args_old(gc, info, vifs, num_vifs); } } @@ -1309,6 +1382,7 @@ static int libxl_vfb_and_vkb_from_device_model_info(libxl_ctx *ctx, static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char **args) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int i; char *vm_path; char *dmargs, *path; @@ -1321,7 +1395,7 @@ static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char * roperm[1].id = domid; roperm[1].perms = XS_PERM_READ; - vm_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/vm", guest_domid)); + vm_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/%d/vm", guest_domid)); i = 0; dmargs_size = 0; @@ -1340,17 +1414,18 @@ static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char * } i++; } - path = libxl_sprintf(ctx, "%s/image/dmargs", vm_path); + path = libxl_sprintf(&gc, "%s/image/dmargs", vm_path); retry_transaction: t = xs_transaction_start(ctx->xsh); xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs)); xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); - xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm)); + xs_set_permissions(ctx->xsh, t, libxl_sprintf(&gc, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm)); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; free(dmargs); + libxl_free_all(&gc); return 0; } @@ -1362,6 +1437,7 @@ static int libxl_create_stubdom(libxl_ctx *ctx, libxl_device_vkb *vkb, libxl_device_model_starting **starting_r) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int i, num_console = 1, ret; libxl_device_console *console; libxl_domain_create_info c_info; @@ -1373,13 +1449,15 @@ static int libxl_create_stubdom(libxl_ctx *ctx, xs_transaction_t t; libxl_device_model_starting *dm_starting = 0; - args = libxl_build_device_model_args(ctx, info, vifs, num_vifs); - if (!args) - return ERROR_FAIL; + args = libxl_build_device_model_args(&gc, info, vifs, num_vifs); + if (!args) { + ret = ERROR_FAIL; + goto out; + } memset(&c_info, 0x00, sizeof(libxl_domain_create_info)); c_info.hvm = 0; - c_info.name = libxl_sprintf(ctx, "%s-dm", _libxl_domid_to_name(ctx, info->domid)); + c_info.name = libxl_sprintf(&gc, "%s-dm", _libxl_domid_to_name(&gc, info->domid)); for (i = 0; i < 16; i++) c_info.uuid[i] = info->uuid[i]; @@ -1387,28 +1465,31 @@ static int libxl_create_stubdom(libxl_ctx *ctx, b_info.max_vcpus = 1; b_info.max_memkb = 32 * 1024; b_info.target_memkb = b_info.max_memkb; - b_info.kernel.path = libxl_abs_path(ctx, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path()); - b_info.u.pv.cmdline = libxl_sprintf(ctx, " -d %d", info->domid); + b_info.kernel.path = libxl_abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path()); + b_info.u.pv.cmdline = libxl_sprintf(&gc, " -d %d", info->domid); b_info.u.pv.ramdisk.path = ""; b_info.u.pv.features = ""; b_info.hvm = 0; ret = libxl_domain_make(ctx, &c_info, &domid); - if (ret) return ret; + if (ret) + goto out_free; ret = libxl_domain_build(ctx, &b_info, domid, &state); - if (ret) return ret; + if (ret) + goto out_free; libxl_write_dmargs(ctx, domid, info->domid, args); - libxl_xs_write(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/image/device-model-domid", libxl_xs_get_dompath(ctx, info->domid)), + libxl_xs_write(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/image/device-model-domid", libxl_xs_get_dompath(&gc, info->domid)), "%d", domid); - libxl_xs_write(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/target", libxl_xs_get_dompath(ctx, domid)), + libxl_xs_write(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/target", libxl_xs_get_dompath(&gc, domid)), "%d", info->domid); ret = xc_domain_set_target(ctx->xch, domid, info->domid); if (ret<0) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "setting target domain %d -> %d", domid, info->domid); - return ERROR_FAIL; + ret = ERROR_FAIL; + goto out_free; } xs_set_target(ctx->xsh, domid, info->domid); @@ -1418,10 +1499,10 @@ static int libxl_create_stubdom(libxl_ctx *ctx, perm[1].perms = XS_PERM_READ; retry_transaction: t = xs_transaction_start(ctx->xsh); - xs_mkdir(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid)); - xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm)); - xs_mkdir(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/%d/device/vfs", domid)); - xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm)); + xs_mkdir(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid)); + xs_set_permissions(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm)); + xs_mkdir(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/%d/device/vfs", domid)); + xs_set_permissions(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm)); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; @@ -1429,26 +1510,32 @@ retry_transaction: for (i = 0; i < num_disks; i++) { disks[i].domid = domid; ret = libxl_device_disk_add(ctx, domid, &disks[i]); - if (ret) return ret; + if (ret) + goto out_free; } for (i = 0; i < num_vifs; i++) { vifs[i].domid = domid; ret = libxl_device_nic_add(ctx, domid, &vifs[i]); - if (ret) return ret; + if (ret) + goto out_free; } vfb->domid = domid; ret = libxl_device_vfb_add(ctx, domid, vfb); - if (ret) return ret; + if (ret) + goto out_free; vkb->domid = domid; ret = libxl_device_vkb_add(ctx, domid, vkb); - if (ret) return ret; + if (ret) + goto out_free; if (info->serial) num_console++; - console = libxl_calloc(ctx, num_console, sizeof(libxl_device_console)); - if (!console) - return ERROR_NOMEM; + console = libxl_calloc(&gc, num_console, sizeof(libxl_device_console)); + if (!console) { + ret = ERROR_NOMEM; + goto out_free; + } for (i = 0; i < num_console; i++) { console[i].devid = i; @@ -1457,28 +1544,34 @@ retry_transaction: if (!i) console[i].build_state = &state; ret = libxl_device_console_add(ctx, domid, &console[i]); - if (ret) return ret; + if (ret) + goto out_free; } if (libxl_create_xenpv_qemu(ctx, vfb, num_console, console, &dm_starting) < 0) { - free(args); - return ERROR_FAIL; + ret = ERROR_FAIL; + goto out_free; } if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) { - free(args); - return ERROR_FAIL; + ret = ERROR_FAIL; + goto out_free; } libxl_domain_unpause(ctx, domid); if (starting_r) { - *starting_r = libxl_calloc(ctx, sizeof(libxl_device_model_starting), 1); + *starting_r = calloc(sizeof(libxl_device_model_starting), 1); (*starting_r)->domid = info->domid; - (*starting_r)->dom_path = libxl_xs_get_dompath(ctx, info->domid); + (*starting_r)->dom_path = libxl_xs_get_dompath(&gc, info->domid); (*starting_r)->for_spawn = NULL; } + ret = 0; + +out_free: free(args); - return 0; +out: + libxl_free_all(&gc); + return ret; } int libxl_create_device_model(libxl_ctx *ctx, @@ -1487,6 +1580,7 @@ int libxl_create_device_model(libxl_ctx *ctx, libxl_device_nic *vifs, int num_vifs, libxl_device_model_starting **starting_r) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path, *logfile; int logfile_w, null; int rc; @@ -1501,48 +1595,55 @@ int libxl_create_device_model(libxl_ctx *ctx, libxl_device_vkb vkb; libxl_vfb_and_vkb_from_device_model_info(ctx, info, &vfb, &vkb); - return libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r); + rc = libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r); + goto out; } - args = libxl_build_device_model_args(ctx, info, vifs, num_vifs); - if (!args) - return ERROR_FAIL; + args = libxl_build_device_model_args(&gc, info, vifs, num_vifs); + if (!args) { + rc = ERROR_FAIL; + goto out; + } - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid); + path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid); xs_mkdir(ctx->xsh, XBT_NULL, path); - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/disable_pf", path), "%d", !info->xen_platform_pci); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/disable_pf", path), "%d", !info->xen_platform_pci); - libxl_create_logfile(ctx, libxl_sprintf(ctx, "qemu-dm-%s", info->dom_name), &logfile); + libxl_create_logfile(ctx, libxl_sprintf(&gc, "qemu-dm-%s", info->dom_name), &logfile); logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644); free(logfile); null = open("/dev/null", O_RDONLY); if (starting_r) { rc = ERROR_NOMEM; - *starting_r = libxl_calloc(ctx, sizeof(libxl_device_model_starting), 1); - if (!*starting_r) goto xit; + *starting_r = calloc(sizeof(libxl_device_model_starting), 1); + if (!*starting_r) + goto out_close; p = *starting_r; - p->for_spawn = libxl_calloc(ctx, sizeof(libxl_spawn_starting), 1); + p->for_spawn = calloc(sizeof(libxl_spawn_starting), 1); } else { p = &buf_starting; p->for_spawn = NULL; } p->domid = info->domid; - p->dom_path = libxl_xs_get_dompath(ctx, info->domid); - if (!p->dom_path) { libxl_free(ctx, p); return ERROR_FAIL; } + p->dom_path = libxl_xs_get_dompath(&gc, info->domid); + if (!p->dom_path) { + rc = ERROR_FAIL; + goto out_close; + } if (info->vncpasswd) { - retry_transaction: +retry_transaction: /* Find uuid and the write the vnc password to xenstore for qemu. */ t = xs_transaction_start(ctx->xsh); - vm_path = libxl_xs_read(ctx,t,libxl_sprintf(ctx, "%s/vm", p->dom_path)); + vm_path = libxl_xs_read(&gc,t,libxl_sprintf(&gc, "%s/vm", p->dom_path)); if (vm_path) { /* Now write the vncpassword into it. */ - pass_stuff = libxl_calloc(ctx, 2, sizeof(char *)); + pass_stuff = libxl_calloc(&gc, 2, sizeof(char *)); pass_stuff[0] = "vncpasswd"; pass_stuff[1] = info->vncpasswd; - libxl_xs_writev(ctx,t,vm_path,pass_stuff); + libxl_xs_writev(&gc,t,vm_path,pass_stuff); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; @@ -1550,19 +1651,22 @@ int libxl_create_device_model(libxl_ctx *ctx, } rc = libxl_spawn_spawn(ctx, p, "device model", dm_xenstore_record_pid); - if (rc < 0) goto xit; + if (rc < 0) + goto out_close; if (!rc) { /* inner child */ libxl_exec(null, logfile_w, logfile_w, - libxl_abs_path(ctx, info->device_model, libxl_private_bindir_path()), + libxl_abs_path(&gc, info->device_model, libxl_private_bindir_path()), args); } rc = 0; - xit: - free(args); + +out_close: close(null); close(logfile_w); - + free(args); +out: + libxl_free_all(&gc); return rc; } @@ -1571,8 +1675,9 @@ int libxl_detach_device_model(libxl_ctx *ctx, { int rc; rc = libxl_spawn_detach(ctx, starting->for_spawn); - if (starting->for_spawn) libxl_free(ctx, starting->for_spawn); - libxl_free(ctx, starting); + if (starting->for_spawn) + free(starting->for_spawn); + free(starting); return rc; } @@ -1591,29 +1696,30 @@ int libxl_confirm_device_model_startup(libxl_ctx *ctx, /******************************************************************************/ -static char *get_blktap2_device(libxl_ctx *ctx, +static char *get_blktap2_device(libxl_gc *gc, const char *name, const char *type) { int minor = tap_ctl_find_minor(type, name); if (minor < 0) return NULL; - return libxl_sprintf(ctx, "/dev/xen/blktap-2/tapdev%d", minor); + return libxl_sprintf(gc, "/dev/xen/blktap-2/tapdev%d", minor); } -static char *make_blktap2_device(libxl_ctx *ctx, +static char *make_blktap2_device(libxl_gc *gc, const char *name, const char *type) { char *params, *devname = NULL; int err; - params = libxl_sprintf(ctx, "%s:%s", type, name); + params = libxl_sprintf(gc, "%s:%s", type, name); err = tap_ctl_create(params, &devname); if (!err) - libxl_ptr_add(ctx, devname); + libxl_ptr_add(gc, devname); return err ? NULL : devname; } int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; char *backend_type; @@ -1621,21 +1727,26 @@ int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *dis unsigned int foffset = 0; int devid; libxl_device device; - int major, minor; + int major, minor, rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) /* leaks front if error */ - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } backend_type = device_disk_backend_type_of_phystype(disk->phystype); devid = device_disk_dev_number(disk->virtpath); if (devid==-1) { XL_LOG(ctx, XL_LOG_ERROR, "Invalid or unsupported" " virtual disk identifier %s", disk->virtpath); - return ERROR_INVAL; + rc = ERROR_INVAL; + goto out_free; } device.backend_devid = devid; @@ -1649,7 +1760,7 @@ int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *dis device_physdisk_major_minor(disk->physpath, &major, &minor); flexarray_set(back, boffset++, "physical-device"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%x:%x", major, minor)); flexarray_set(back, boffset++, "params"); flexarray_set(back, boffset++, disk->physpath); @@ -1665,25 +1776,27 @@ int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *dis if (!tap_ctl_check(&msg)) { const char *type = device_disk_string_of_phystype(disk->phystype); char *dev; - dev = get_blktap2_device(ctx, disk->physpath, type); - if (!dev) - dev = make_blktap2_device(ctx, disk->physpath, type); + dev = get_blktap2_device(&gc, disk->physpath, type); if (!dev) - return ERROR_FAIL; + dev = make_blktap2_device(&gc, disk->physpath, type); + if (!dev) { + rc = ERROR_FAIL; + goto out_free; + } flexarray_set(back, boffset++, "tapdisk-params"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath)); flexarray_set(back, boffset++, "params"); - flexarray_set(back, boffset++, libxl_strdup(ctx, dev)); + flexarray_set(back, boffset++, libxl_strdup(&gc, dev)); backend_type = "phy"; device_physdisk_major_minor(dev, &major, &minor); flexarray_set(back, boffset++, "physical-device"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%x:%x", major, minor)); device.backend_kind = DEVICE_VBD; break; } flexarray_set(back, boffset++, "params"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath)); device.backend_kind = DEVICE_TAP; @@ -1691,19 +1804,20 @@ int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *dis } default: XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", disk->phystype); - return ERROR_INVAL; + rc = ERROR_INVAL; + goto out_free; } flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", disk->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", disk->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "removable"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", (disk->unpluggable) ? 1 : 0)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", (disk->unpluggable) ? 1 : 0)); flexarray_set(back, boffset++, "bootable"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "dev"); flexarray_set(back, boffset++, disk->virtpath); flexarray_set(back, boffset++, "type"); @@ -1712,11 +1826,11 @@ int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *dis flexarray_set(back, boffset++, disk->readwrite ? "w" : "r"); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", disk->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", disk->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(front, foffset++, "virtual-device"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", devid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", devid)); flexarray_set(front, foffset++, "device-type"); flexarray_set(front, foffset++, disk->is_cdrom ? "cdrom" : "disk"); @@ -1726,11 +1840,17 @@ int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *dis } libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); + + rc = 0; + +out_free: flexarray_free(back); flexarray_free(front); - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_device_disk_del(libxl_ctx *ctx, @@ -1750,9 +1870,10 @@ int libxl_device_disk_del(libxl_ctx *ctx, return libxl_device_del(ctx, &device, wait); } -const char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk) +char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk) { - char *dev = NULL; + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *dev = NULL, *ret; int phystype = disk->phystype; switch (phystype) { case PHYSTYPE_PHY: { @@ -1767,9 +1888,9 @@ const char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *d const char *msg; if (!tap_ctl_check(&msg)) { const char *type = device_disk_string_of_phystype(phystype); - dev = get_blktap2_device(ctx, disk->physpath, type); + dev = get_blktap2_device(&gc, disk->physpath, type); if (!dev) - dev = make_blktap2_device(ctx, disk->physpath, type); + dev = make_blktap2_device(&gc, disk->physpath, type); } break; } @@ -1777,7 +1898,9 @@ const char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *d XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", phystype); break; } - return dev; + ret = strdup(dev); + libxl_free_all(&gc); + return ret; } int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk) @@ -1795,31 +1918,36 @@ int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk) /******************************************************************************/ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; unsigned int foffset = 0; libxl_device device; char *dompath, **l; - unsigned int nb; + unsigned int nb, rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } if (nic->devid == -1) { - if (!(dompath = libxl_xs_get_dompath(ctx, domid))) { - return ERROR_FAIL; + if (!(dompath = libxl_xs_get_dompath(&gc, domid))) { + rc = ERROR_FAIL; + goto out_free; } - if (!(l = libxl_xs_directory(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/device/vif", dompath), &nb))) { + if (!(l = libxl_xs_directory(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/device/vif", dompath), &nb))) { nic->devid = 0; } else { nic->devid = strtoul(l[nb - 1], NULL, 10) + 1; - libxl_free(ctx, l); } } @@ -1831,30 +1959,30 @@ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic) device.kind = DEVICE_VIF; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", nic->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "script"); flexarray_set(back, boffset++, nic->script); flexarray_set(back, boffset++, "mac"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", nic->mac[0], nic->mac[1], nic->mac[2], nic->mac[3], nic->mac[4], nic->mac[5])); flexarray_set(back, boffset++, "bridge"); - flexarray_set(back, boffset++, libxl_strdup(ctx, nic->bridge)); + flexarray_set(back, boffset++, libxl_strdup(&gc, nic->bridge)); flexarray_set(back, boffset++, "handle"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->devid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", nic->devid)); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", nic->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(front, foffset++, "handle"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->devid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", nic->devid)); flexarray_set(front, foffset++, "mac"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", nic->mac[0], nic->mac[1], nic->mac[2], nic->mac[3], nic->mac[4], nic->mac[5])); if (0 /* protocol != native*/) { @@ -1863,13 +1991,17 @@ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic) } libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); /* FIXME: wait for plug */ + rc = 0; +out_free: flexarray_free(back); flexarray_free(front); - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_device_nic_del(libxl_ctx *ctx, @@ -1900,87 +2032,94 @@ void libxl_free_nics_list(libxl_nicinfo *nics, unsigned int nb) libxl_nicinfo *libxl_list_nics(libxl_ctx *ctx, uint32_t domid, unsigned int *nb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dompath, *nic_path_fe; char **l, **list; char *val, *tok; unsigned int nb_nics, i; libxl_nicinfo *res, *nics; - dompath = libxl_xs_get_dompath(ctx, domid); - if (!dompath) { - return NULL; - } - list = l = libxl_xs_directory(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/device/vif", dompath), &nb_nics); - if (!l) { - return NULL; - } + dompath = libxl_xs_get_dompath(&gc, domid); + if (!dompath) + goto err; + list = l = libxl_xs_directory(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/device/vif", dompath), &nb_nics); + if (!l) + goto err; nics = res = calloc(nb_nics, sizeof (libxl_device_nic)); - if (!res) { - libxl_free(ctx, l); - return NULL; - } + if (!res) + goto err; for (*nb = nb_nics; nb_nics > 0; --nb_nics, ++l, ++nics) { - nic_path_fe = libxl_sprintf(ctx, "%s/device/vif/%s", dompath, *l); + nic_path_fe = libxl_sprintf(&gc, "%s/device/vif/%s", dompath, *l); nics->backend = xs_read(ctx->xsh, XBT_NULL, - libxl_sprintf(ctx, "%s/backend", nic_path_fe), NULL); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", nic_path_fe)); + libxl_sprintf(&gc, "%s/backend", nic_path_fe), NULL); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", nic_path_fe)); nics->backend_id = val ? strtoul(val, NULL, 10) : -1; nics->devid = strtoul(*l, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", nic_path_fe)); nics->state = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", nic_path_fe)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { nics->mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/event-channel", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/event-channel", nic_path_fe)); nics->evtch = val ? strtol(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/tx-ring-ref", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/tx-ring-ref", nic_path_fe)); nics->rref_tx = val ? strtol(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/rx-ring-ref", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/rx-ring-ref", nic_path_fe)); nics->rref_rx = val ? strtol(val, NULL, 10) : -1; nics->frontend = xs_read(ctx->xsh, XBT_NULL, - libxl_sprintf(ctx, "%s/frontend", nics->backend), NULL); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend-id", nics->backend)); + libxl_sprintf(&gc, "%s/frontend", nics->backend), NULL); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", nics->backend)); nics->frontend_id = val ? strtoul(val, NULL, 10) : -1; nics->script = xs_read(ctx->xsh, XBT_NULL, - libxl_sprintf(ctx, "%s/script", nics->backend), NULL); + libxl_sprintf(&gc, "%s/script", nics->backend), NULL); } + libxl_free_all(&gc); return res; +err: + libxl_free_all(&gc); + return NULL; } /******************************************************************************/ int libxl_device_net2_add(libxl_ctx *ctx, uint32_t domid, libxl_device_net2 *net2) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front, *back; unsigned int boffset = 0, foffset = 0; libxl_device device; char *dompath, *dom, **l; unsigned int nb; + int rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto err; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto err_free; + } - if (!(dompath = libxl_xs_get_dompath(ctx, domid))) { - return ERROR_FAIL; + if (!(dompath = libxl_xs_get_dompath(&gc, domid))) { + rc = ERROR_FAIL; + goto err_free; } - dom = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/name", dompath)); + dom = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/name", dompath)); if (net2->devid == -1) { - if (!(l = libxl_xs_directory(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/device/vif2", dompath), &nb))) { + if (!(l = libxl_xs_directory(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/device/vif2", dompath), &nb))) { net2->devid = 0; } else { net2->devid = strtoul(l[nb - 1], NULL, 10) + 1; - libxl_free(ctx, l); } } @@ -1994,129 +2133,132 @@ int libxl_device_net2_add(libxl_ctx *ctx, uint32_t domid, libxl_device_net2 *net flexarray_set(back, boffset++, "domain"); flexarray_set(back, boffset++, dom); flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->domid)); flexarray_set(back, boffset++, "local-trusted"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->back_trusted)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->back_trusted)); flexarray_set(back, boffset++, "mac"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", net2->back_mac[0], net2->back_mac[1], net2->back_mac[2], net2->back_mac[3], net2->back_mac[4], net2->back_mac[5])); flexarray_set(back, boffset++, "remote-trusted"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->trusted)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->trusted)); flexarray_set(back, boffset++, "remote-mac"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", net2->front_mac[0], net2->front_mac[1], net2->front_mac[2], net2->front_mac[3], net2->front_mac[4], net2->front_mac[5])); flexarray_set(back, boffset++, "max-bypasses"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->max_bypasses)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->max_bypasses)); flexarray_set(back, boffset++, "filter-mac"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", !!(net2->filter_mac))); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", !!(net2->filter_mac))); flexarray_set(back, boffset++, "handle"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->devid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->devid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); flexarray_set(back, boffset++, "1"); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", net2->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->backend_domid)); flexarray_set(front, foffset++, "local-trusted"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", net2->trusted)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->trusted)); flexarray_set(front, foffset++, "mac"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", net2->front_mac[0], net2->front_mac[1], net2->front_mac[2], net2->front_mac[3], net2->front_mac[4], net2->front_mac[5])); flexarray_set(front, foffset++, "remote-trusted"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", net2->back_trusted)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->back_trusted)); flexarray_set(front, foffset++, "remote-mac"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", net2->back_mac[0], net2->back_mac[1], net2->back_mac[2], net2->back_mac[3], net2->back_mac[4], net2->back_mac[5])); flexarray_set(front, foffset++, "filter-mac"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", !!(net2->filter_mac))); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", !!(net2->filter_mac))); flexarray_set(front, foffset++, "state"); flexarray_set(front, foffset++, "1"); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); /* FIXME: wait for plug */ + rc = 0; +err_free: flexarray_free(back); flexarray_free(front); - return 0; +err: + libxl_free_all(&gc); + return rc; } libxl_net2info *libxl_device_net2_list(libxl_ctx *ctx, uint32_t domid, unsigned int *nb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dompath, *net2_path_fe; char **l; char *val, *tok; unsigned int nb_net2s, i; libxl_net2info *res, *net2s; - dompath = libxl_xs_get_dompath(ctx, domid); - if (!dompath) { - return NULL; - } - l = libxl_xs_directory(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/device/vif2", dompath), &nb_net2s); - if (!l) { - return NULL; - } - res = libxl_calloc(ctx, nb_net2s, sizeof (libxl_net2info)); - if (!res) { - libxl_free(ctx, l); - return NULL; - } + dompath = libxl_xs_get_dompath(&gc, domid); + if (!dompath) + goto err; + l = libxl_xs_directory(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/device/vif2", dompath), &nb_net2s); + if (!l) + goto err; + res = calloc(nb_net2s, sizeof (libxl_net2info)); + if (!res) + goto err; net2s = res; for (*nb = nb_net2s; nb_net2s > 0; --nb_net2s, ++l, ++net2s) { - net2_path_fe = libxl_sprintf(ctx, "%s/device/vif2/%s", dompath, *l); + net2_path_fe = libxl_sprintf(&gc, "%s/device/vif2/%s", dompath, *l); - net2s->backend = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/backend", net2_path_fe)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", net2_path_fe)); + net2s->backend = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/backend", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", net2_path_fe)); net2s->backend_id = val ? strtoul(val, NULL, 10) : -1; net2s->devid = strtoul(*l, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", net2_path_fe)); net2s->state = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", net2_path_fe)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { net2s->mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-trusted", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-trusted", net2_path_fe)); net2s->trusted = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-mac", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-mac", net2_path_fe)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { net2s->back_mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", net2_path_fe)); net2s->filter_mac = val ? strtoul(val, NULL, 10) : -1; - net2s->frontend = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/frontend", net2s->backend)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend-id", net2s->backend)); + net2s->frontend = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/frontend", net2s->backend)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", net2s->backend)); net2s->frontend_id = val ? strtoul(val, NULL, 10) : -1; - libxl_free(ctx, net2_path_fe); } - libxl_free(ctx, l); + libxl_free_all(&gc); return res; +err: + libxl_free_all(&gc); + return NULL; } int libxl_device_net2_del(libxl_ctx *ctx, libxl_device_net2 *net2, int wait) @@ -2137,21 +2279,23 @@ int libxl_device_net2_del(libxl_ctx *ctx, libxl_device_net2 *net2, int wait) /******************************************************************************/ int libxl_device_console_add(libxl_ctx *ctx, uint32_t domid, libxl_device_console *console) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; unsigned int foffset = 0; libxl_device device; + int rc; if (console->build_state) { xs_transaction_t t; - char **ents = (char **) libxl_calloc(ctx, 9, sizeof(char *)); + char **ents = (char **) libxl_calloc(&gc, 9, sizeof(char *)); ents[0] = "console/port"; - ents[1] = libxl_sprintf(ctx, "%"PRIu32, console->build_state->console_port); + ents[1] = libxl_sprintf(&gc, "%"PRIu32, console->build_state->console_port); ents[2] = "console/ring-ref"; - ents[3] = libxl_sprintf(ctx, "%lu", console->build_state->console_mfn); + ents[3] = libxl_sprintf(&gc, "%lu", console->build_state->console_mfn); ents[4] = "console/limit"; - ents[5] = libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT); + ents[5] = libxl_sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT); ents[6] = "console/type"; if (console->constype == CONSTYPE_XENCONSOLED) ents[7] = "xenconsoled"; @@ -2159,18 +2303,22 @@ int libxl_device_console_add(libxl_ctx *ctx, uint32_t domid, libxl_device_consol ents[7] = "ioemu"; retry_transaction: t = xs_transaction_start(ctx->xsh); - libxl_xs_writev(ctx, t, libxl_xs_get_dompath(ctx, console->domid), ents); + libxl_xs_writev(&gc, t, libxl_xs_get_dompath(&gc, console->domid), ents); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; } front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } device.backend_devid = console->devid; device.backend_domid = console->backend_domid; @@ -2180,22 +2328,22 @@ retry_transaction: device.kind = DEVICE_CONSOLE; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", console->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", console->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "domain"); - flexarray_set(back, boffset++, _libxl_domid_to_name(ctx, domid)); + flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid)); flexarray_set(back, boffset++, "protocol"); flexarray_set(back, boffset++, LIBXL_XENCONSOLE_PROTOCOL); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", console->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", console->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(front, foffset++, "limit"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT)); flexarray_set(front, foffset++, "protocol"); flexarray_set(front, foffset++, LIBXL_XENCONSOLE_PROTOCOL); flexarray_set(front, foffset++, "type"); @@ -2205,29 +2353,38 @@ retry_transaction: flexarray_set(front, foffset++, "ioemu"); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); + rc = 0; +out_free: flexarray_free(back); flexarray_free(front); - - return 0; +out: + libxl_free_all(&gc); + return rc; } /******************************************************************************/ int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; unsigned int foffset = 0; libxl_device device; + int rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } device.backend_devid = vkb->devid; device.backend_domid = vkb->backend_domid; @@ -2237,26 +2394,29 @@ int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb) device.kind = DEVICE_VKBD; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vkb->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vkb->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "domain"); - flexarray_set(back, boffset++, _libxl_domid_to_name(ctx, domid)); + flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid)); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", vkb->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", vkb->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); + rc = 0; +out_free: flexarray_free(back); flexarray_free(front); - - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_device_vkb_clean_shutdown(libxl_ctx *ctx, uint32_t domid) @@ -2271,16 +2431,17 @@ int libxl_device_vkb_hard_shutdown(libxl_ctx *ctx, uint32_t domid) libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *num) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *be_path_tap, *be_path_vbd; libxl_device_disk *dend, *disks, *ret = NULL; char **b, **l = NULL; unsigned int numl; char *type; - be_path_vbd = libxl_sprintf(ctx, "%s/backend/vbd/%d", libxl_xs_get_dompath(ctx, 0), domid); - be_path_tap = libxl_sprintf(ctx, "%s/backend/tap/%d", libxl_xs_get_dompath(ctx, 0), domid); + be_path_vbd = libxl_sprintf(&gc, "%s/backend/vbd/%d", libxl_xs_get_dompath(&gc, 0), domid); + be_path_tap = libxl_sprintf(&gc, "%s/backend/tap/%d", libxl_xs_get_dompath(&gc, 0), domid); - b = l = libxl_xs_directory(ctx, XBT_NULL, be_path_vbd, &numl); + b = l = libxl_xs_directory(&gc, XBT_NULL, be_path_vbd, &numl); if (l) { ret = realloc(ret, sizeof(libxl_device_disk) * numl); disks = ret; @@ -2289,20 +2450,19 @@ libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *n for (; disks < dend; ++disks, ++l) { disks->backend_domid = 0; disks->domid = domid; - disks->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/params", be_path_vbd, *l)); - libxl_string_to_phystype(ctx, libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/type", be_path_vbd, *l)), &(disks->phystype)); - disks->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/dev", be_path_vbd, *l)); - disks->unpluggable = atoi(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/removable", be_path_vbd, *l))); - if (!strcmp(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/mode", be_path_vbd, *l)), "w")) + disks->physpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/params", be_path_vbd, *l)); + libxl_string_to_phystype(ctx, libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/type", be_path_vbd, *l)), &(disks->phystype)); + disks->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/dev", be_path_vbd, *l)); + disks->unpluggable = atoi(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/removable", be_path_vbd, *l))); + if (!strcmp(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/mode", be_path_vbd, *l)), "w")) disks->readwrite = 1; else disks->readwrite = 0; - type = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/device-type", libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/frontend", be_path_vbd, *l)))); + type = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/device-type", libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/frontend", be_path_vbd, *l)))); disks->is_cdrom = !strcmp(type, "cdrom"); } - libxl_free(ctx, b); } - b = l = libxl_xs_directory(ctx, XBT_NULL, be_path_tap, &numl); + b = l = libxl_xs_directory(&gc, XBT_NULL, be_path_tap, &numl); if (l) { ret = realloc(ret, sizeof(libxl_device_disk) * (*num + numl)); disks = ret + *num; @@ -2310,51 +2470,54 @@ libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *n for (dend = ret + *num; disks < dend; ++disks, ++l) { disks->backend_domid = 0; disks->domid = domid; - disks->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/params", be_path_tap, *l)); - libxl_string_to_phystype(ctx, libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/type", be_path_tap, *l)), &(disks->phystype)); - disks->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/dev", be_path_tap, *l)); - disks->unpluggable = atoi(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/removable", be_path_tap, *l))); - if (!strcmp(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/mode", be_path_tap, *l)), "w")) + disks->physpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/params", be_path_tap, *l)); + libxl_string_to_phystype(ctx, libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/type", be_path_tap, *l)), &(disks->phystype)); + disks->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/dev", be_path_tap, *l)); + disks->unpluggable = atoi(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/removable", be_path_tap, *l))); + if (!strcmp(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/mode", be_path_tap, *l)), "w")) disks->readwrite = 1; else disks->readwrite = 0; - type = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/device-type", libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/frontend", be_path_tap, *l)))); + type = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/device-type", libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/frontend", be_path_tap, *l)))); disks->is_cdrom = !strcmp(type, "cdrom"); } - libxl_free(ctx, b); } + libxl_free_all(&gc); return ret; } int libxl_device_disk_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, libxl_diskinfo *diskinfo) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dompath, *diskpath; char *val; - dompath = libxl_xs_get_dompath(ctx, domid); + dompath = libxl_xs_get_dompath(&gc, domid); diskinfo->devid = device_disk_dev_number(disk->virtpath); /* tap devices entries in xenstore are written as vbd devices. */ - diskpath = libxl_sprintf(ctx, "%s/device/vbd/%d", dompath, diskinfo->devid); - diskinfo->backend = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/backend", diskpath)); + diskpath = libxl_sprintf(&gc, "%s/device/vbd/%d", dompath, diskinfo->devid); + diskinfo->backend = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/backend", diskpath)); if (!diskinfo->backend) { + libxl_free_all(&gc); return ERROR_FAIL; } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", diskpath)); diskinfo->backend_id = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", diskpath)); diskinfo->state = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/event-channel", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/event-channel", diskpath)); diskinfo->evtch = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/ring-ref", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/ring-ref", diskpath)); diskinfo->rref = val ? strtoul(val, NULL, 10) : -1; - diskinfo->frontend = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/frontend", diskinfo->backend)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend-id", diskinfo->backend)); + diskinfo->frontend = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/frontend", diskinfo->backend)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", diskinfo->backend)); diskinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1; + libxl_free_all(&gc); return 0; } @@ -2376,6 +2539,7 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) } if (i == num) { XL_LOG(ctx, XL_LOG_ERROR, "Virtual device not found"); + free(disks); return ERROR_FAIL; } libxl_device_disk_del(ctx, disks + i, 1); @@ -2388,28 +2552,30 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) libxl_device_disk_add(ctx, stubdomid, disk); disk->domid = domid; } + free(disks); return 0; } /******************************************************************************/ -static int libxl_build_xenpv_qemu_args(libxl_ctx *ctx, +static int libxl_build_xenpv_qemu_args(libxl_gc *gc, libxl_device_vfb *vfb, int num_console, libxl_device_console *console, libxl_device_model_info *info) { + libxl_ctx *ctx = libxl_gc_owner(gc); int i = 0, j = 0, num = 0; memset(info, 0x00, sizeof(libxl_device_model_info)); info->vnc = vfb->vnc; if (vfb->vnclisten) - info->vnclisten = libxl_strdup(ctx, vfb->vnclisten); + info->vnclisten = libxl_strdup(gc, vfb->vnclisten); info->vncdisplay = vfb->vncdisplay; info->vncunused = vfb->vncunused; if (vfb->vncpasswd) info->vncpasswd = vfb->vncpasswd; if (vfb->keymap) - info->keymap = libxl_strdup(ctx, vfb->keymap); + info->keymap = libxl_strdup(gc, vfb->keymap); info->sdl = vfb->sdl; info->opengl = vfb->opengl; for (i = 0; i < num_console; i++) { @@ -2420,9 +2586,9 @@ static int libxl_build_xenpv_qemu_args(libxl_ctx *ctx, uint32_t guest_domid; if (libxl_is_stubdom(ctx, vfb->domid, &guest_domid)) { char *filename; - char *name = libxl_sprintf(ctx, "qemu-dm-%s", _libxl_domid_to_name(ctx, guest_domid)); + char *name = libxl_sprintf(gc, "qemu-dm-%s", _libxl_domid_to_name(gc, guest_domid)); libxl_create_logfile(ctx, name, &filename); - info->serial = libxl_sprintf(ctx, "file:%s", filename); + info->serial = libxl_sprintf(gc, "file:%s", filename); free(filename); } else { info->serial = "pty"; @@ -2430,7 +2596,7 @@ static int libxl_build_xenpv_qemu_args(libxl_ctx *ctx, num--; } if (num > 0) { - info->extra = (char **) libxl_calloc(ctx, num * 2 + 1, sizeof(char *)); + info->extra = (char **) libxl_calloc(gc, num * 2 + 1, sizeof(char *)); for (j = 0; j < num * 2; j = j + 2) { info->extra[j] = "-serial"; info->extra[j + 1] = "pty"; @@ -2438,8 +2604,8 @@ static int libxl_build_xenpv_qemu_args(libxl_ctx *ctx, info->extra[j] = NULL; } info->domid = vfb->domid; - info->dom_name = _libxl_domid_to_name(ctx, vfb->domid); - info->device_model = libxl_abs_path(ctx, "qemu-dm", libxl_libexec_path()); + info->dom_name = _libxl_domid_to_name(gc, vfb->domid); + info->device_model = libxl_abs_path(gc, "qemu-dm", libxl_libexec_path()); info->type = XENPV; return 0; } @@ -2448,27 +2614,35 @@ int libxl_create_xenpv_qemu(libxl_ctx *ctx, libxl_device_vfb *vfb, int num_console, libxl_device_console *console, libxl_device_model_starting **starting_r) { + libxl_gc gc = LIBXL_INIT_GC(ctx); libxl_device_model_info info; - libxl_build_xenpv_qemu_args(ctx, vfb, num_console, console, &info); + libxl_build_xenpv_qemu_args(&gc, vfb, num_console, console, &info); libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r); + libxl_free_all(&gc); return 0; } int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; unsigned int foffset = 0; libxl_device device; + int rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } device.backend_devid = vfb->devid; device.backend_domid = vfb->backend_domid; @@ -2478,27 +2652,27 @@ int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb) device.kind = DEVICE_VFB; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "domain"); - flexarray_set(back, boffset++, _libxl_domid_to_name(ctx, domid)); + flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid)); flexarray_set(back, boffset++, "vnc"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vnc)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vnc)); flexarray_set(back, boffset++, "vnclisten"); flexarray_set(back, boffset++, vfb->vnclisten); flexarray_set(back, boffset++, "vncpasswd"); flexarray_set(back, boffset++, vfb->vncpasswd); flexarray_set(back, boffset++, "vncdisplay"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncdisplay)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vncdisplay)); flexarray_set(back, boffset++, "vncunused"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncunused)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vncunused)); flexarray_set(back, boffset++, "sdl"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->sdl)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->sdl)); flexarray_set(back, boffset++, "opengl"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->opengl)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->opengl)); if (vfb->xauthority) { flexarray_set(back, boffset++, "xauthority"); flexarray_set(back, boffset++, vfb->xauthority); @@ -2509,17 +2683,20 @@ int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb) } flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", vfb->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", vfb->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); + rc = 0; +out_free: flexarray_free(front); flexarray_free(back); - - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_device_vfb_clean_shutdown(libxl_ctx *ctx, uint32_t domid) @@ -2536,81 +2713,90 @@ int libxl_device_vfb_hard_shutdown(libxl_ctx *ctx, uint32_t domid) int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *mem, *endptr; uint32_t memorykb; - char *dompath = libxl_xs_get_dompath(ctx, domid); + char *dompath = libxl_xs_get_dompath(&gc, domid); + int rc = 1; - mem = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/target", dompath)); + mem = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", dompath)); if (!mem) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot get memory info from %s/memory/target\n", dompath); - return 1; + goto out; } memorykb = strtoul(mem, &endptr, 10); if (*endptr != '\0') { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "invalid memory %s from %s/memory/target\n", mem, dompath); - return 1; + goto out; } if (max_memkb < memorykb) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "memory_static_max must be greater than or or equal to memory_dynamic_max\n"); - return 1; + goto out; } if (domid != 0) - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/static-max", dompath), "%"PRIu32, max_memkb); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/static-max", dompath), "%"PRIu32, max_memkb); - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce) { - int rc = 0; + libxl_gc gc = LIBXL_INIT_GC(ctx); + int rc = 1; uint32_t memorykb = 0, videoram = 0; char *memmax, *endptr, *videoram_s = NULL; - char *dompath = libxl_xs_get_dompath(ctx, domid); + char *dompath = libxl_xs_get_dompath(&gc, domid); xc_domaininfo_t info; libxl_dominfo ptr; char *uuid; if (domid) { - memmax = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/static-max", dompath)); + memmax = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/static-max", dompath)); if (!memmax) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot get memory info from %s/memory/static-max\n", dompath); - return 1; + goto out; } memorykb = strtoul(memmax, &endptr, 10); if (*endptr != '\0') { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "invalid max memory %s from %s/memory/static-max\n", memmax, dompath); - return 1; + goto out; } if (target_memkb > memorykb) { XL_LOG(ctx, XL_LOG_ERROR, "memory_dynamic_max must be less than or equal to memory_static_max\n"); - return 1; + goto out; } } - videoram_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/videoram", dompath)); + videoram_s = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/videoram", dompath)); videoram = videoram_s ? atoi(videoram_s) : 0; - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/target", dompath), "%"PRIu32, target_memkb); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", dompath), "%"PRIu32, target_memkb); rc = xc_domain_getinfolist(ctx->xch, domid, 1, &info); if (rc != 1 || info.domain != domid) - return rc; + goto out; xcinfo2xlinfo(&info, &ptr); uuid = libxl_uuid2string(ctx, ptr.uuid); - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/vm/%s/memory", uuid), "%"PRIu32, target_memkb / 1024); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/vm/%s/memory", uuid), "%"PRIu32, target_memkb / 1024); if (enforce || !domid) memorykb = target_memkb; rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb + LIBXL_MAXMEM_CONSTANT); if (rc != 0) - return rc; + goto out; rc = xc_domain_memory_set_pod_target(ctx->xch, domid, (target_memkb - videoram) / 4, NULL, NULL, NULL); + +out: + libxl_free_all(&gc); return rc; } @@ -2784,26 +2970,31 @@ int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, int libxl_set_vcpucount(libxl_ctx *ctx, uint32_t domid, uint32_t count) { + libxl_gc gc = LIBXL_INIT_GC(ctx); xc_domaininfo_t domaininfo; char *dompath; - int i; + int i, rc = ERROR_FAIL; if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting domain info list"); - return ERROR_FAIL; + goto out; } if (!count || ((domaininfo.max_vcpu_id + 1) < count)) { - return ERROR_INVAL; + rc = ERROR_INVAL; + goto out; } - if (!(dompath = libxl_xs_get_dompath(ctx, domid))) - return ERROR_FAIL; + if (!(dompath = libxl_xs_get_dompath(&gc, domid))) + goto out; for (i = 0; i <= domaininfo.max_vcpu_id; ++i) { - libxl_xs_write(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/cpu/%u/availability", dompath, i), + libxl_xs_write(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/cpu/%u/availability", dompath, i), "%s", ((1 << i) & ((1 << count) - 1)) ? "online" : "offline"); } - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } /* @@ -2916,10 +3107,12 @@ int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid, char *trigger_name, uint3 int libxl_send_sysrq(libxl_ctx *ctx, uint32_t domid, char sysrq) { - char *dompath = libxl_xs_get_dompath(ctx, domid); + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *dompath = libxl_xs_get_dompath(&gc, domid); - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/control/sysrq", dompath), "%c", sysrq); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/control/sysrq", dompath), "%c", sysrq); + libxl_free_all(&gc); return 0; } @@ -3006,20 +3199,24 @@ void libxl_xen_console_read_finish(libxl_ctx *ctx, uint32_t libxl_vm_get_start_time(libxl_ctx *ctx, uint32_t domid) { - char *dompath = libxl_xs_get_dompath(ctx, domid); + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *dompath = libxl_xs_get_dompath(&gc, domid); char *vm_path, *start_time; + uint32_t ret; vm_path = libxl_xs_read( - ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vm", dompath)); + &gc, XBT_NULL, libxl_sprintf(&gc, "%s/vm", dompath)); start_time = libxl_xs_read( - ctx, XBT_NULL, libxl_sprintf(ctx, "%s/start_time", vm_path)); + &gc, XBT_NULL, libxl_sprintf(&gc, "%s/start_time", vm_path)); if (start_time == NULL) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, -1, "Can't get start time of domain '%d'", domid); - return -1; + ret = -1; + }else{ + ret = strtoul(start_time, NULL, 10); } - - return strtoul(start_time, NULL, 10); + libxl_free_all(&gc); + return ret; } char *libxl_tmem_list(libxl_ctx *ctx, uint32_t domid, int use_long) diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 5d513a711c..92950f8af5 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -78,10 +78,6 @@ typedef struct { xc_interface *xch; struct xs_handle *xsh; - /* mini-GC */ - int alloc_maxsize; - void **alloc_ptrs; - /* for callers who reap children willy-nilly; caller must only * set this after libxl_init and before any other call - or * may leave them untouched */ @@ -491,7 +487,7 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk); /* * Make a disk available in this domain. Returns path to a device. */ -const char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk); +char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk); int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk); typedef struct { diff --git a/tools/libxl/libxl_bootloader.c b/tools/libxl/libxl_bootloader.c index e9c9c2f59f..e7e88ce3d1 100644 --- a/tools/libxl/libxl_bootloader.c +++ b/tools/libxl/libxl_bootloader.c @@ -30,7 +30,7 @@ #define XENCONSOLED_BUF_SIZE 16 #define BOOTLOADER_BUF_SIZE 1024 -static char **make_bootloader_args(libxl_ctx *ctx, +static char **make_bootloader_args(libxl_gc *gc, libxl_domain_build_info *info, uint32_t domid, const char *fifo, const char *disk) @@ -45,20 +45,20 @@ static char **make_bootloader_args(libxl_ctx *ctx, flexarray_set(args, nr++, (char *)info->u.pv.bootloader); if (info->kernel.path) - flexarray_set(args, nr++, libxl_sprintf(ctx, "--kernel=%s", info->kernel.path)); + flexarray_set(args, nr++, libxl_sprintf(gc, "--kernel=%s", info->kernel.path)); if (info->u.pv.ramdisk.path) - flexarray_set(args, nr++, libxl_sprintf(ctx, "--ramdisk=%s", info->u.pv.ramdisk.path)); + flexarray_set(args, nr++, libxl_sprintf(gc, "--ramdisk=%s", info->u.pv.ramdisk.path)); if (info->u.pv.cmdline && *info->u.pv.cmdline != '\0') - flexarray_set(args, nr++, libxl_sprintf(ctx, "--args=%s", info->u.pv.cmdline)); + flexarray_set(args, nr++, libxl_sprintf(gc, "--args=%s", info->u.pv.cmdline)); - flexarray_set(args, nr++, libxl_sprintf(ctx, "--output=%s", fifo)); + flexarray_set(args, nr++, libxl_sprintf(gc, "--output=%s", fifo)); flexarray_set(args, nr++, "--output-format=simple0"); - flexarray_set(args, nr++, libxl_sprintf(ctx, "--output-directory=%s", "/var/run/libxl/")); + flexarray_set(args, nr++, libxl_sprintf(gc, "--output-directory=%s", "/var/run/libxl/")); if (info->u.pv.bootloader_args) { char *saveptr; /* Operate on a duplicate since strtok modifes the argument */ - char *dup = libxl_strdup(ctx, info->u.pv.bootloader_args); + char *dup = libxl_strdup(gc, info->u.pv.bootloader_args); char *t = strtok_r(dup, " \t\n", &saveptr); do { flexarray_set(args, nr++, t); @@ -161,7 +161,7 @@ static pid_t fork_exec_bootloader(int *master, char *arg0, char **args) * if there is actual data to write, otherwise this would loop too fast, * eating up CPU time. */ -static char * bootloader_interact(libxl_ctx *ctx, int xenconsoled_fd, int bootloader_fd, int fifo_fd) +static char * bootloader_interact(libxl_gc *gc, int xenconsoled_fd, int bootloader_fd, int fifo_fd) { int ret; @@ -263,7 +263,7 @@ static char * bootloader_interact(libxl_ctx *ctx, int xenconsoled_fd, int bootlo } } - libxl_ptr_add(ctx, output); + libxl_ptr_add(gc, output); return output; out_err: @@ -300,8 +300,8 @@ int libxl_run_bootloader(libxl_ctx *ctx, libxl_device_disk *disk, uint32_t domid) { - int ret; - + libxl_gc gc = LIBXL_INIT_GC(ctx); + int ret, rc = 0; char *fifo = NULL; const char *diskpath = NULL; char **args = NULL; @@ -322,49 +322,48 @@ int libxl_run_bootloader(libxl_ctx *ctx, struct stat st_buf; if (info->hvm || !info->u.pv.bootloader) - return 0; + goto out; + rc = ERROR_INVAL; if (!disk) - return ERROR_INVAL; + goto out; + rc = ERROR_FAIL; ret = mkdir("/var/run/libxl/", S_IRWXU); if (ret < 0 && errno != EEXIST) - return ERROR_FAIL; + goto out; ret = stat("/var/run/libxl/", &st_buf); if (ret < 0) - return ERROR_FAIL; + goto out; if (!S_ISDIR(st_buf.st_mode)) - return ERROR_FAIL; + goto out; tempdir = mkdtemp(tempdir_template); if (tempdir == NULL) - return ERROR_FAIL; + goto out; ret = asprintf(&fifo, "%s/fifo", tempdir); if (ret < 0) { - ret = ERROR_FAIL; fifo = NULL; - goto out; + goto out_close; } ret = mkfifo(fifo, 0600); if (ret < 0) { - ret = ERROR_FAIL; - goto out; + goto out_close; } diskpath = libxl_device_disk_local_attach(ctx, disk); if (!diskpath) { - ret = ERROR_FAIL; - goto out; + goto out_close; } - args = make_bootloader_args(ctx, info, domid, fifo, diskpath); + args = make_bootloader_args(&gc, info, domid, fifo, diskpath); if (args == NULL) { - ret = ERROR_NOMEM; - goto out; + rc = ERROR_NOMEM; + goto out_close; } /* @@ -381,17 +380,15 @@ int libxl_run_bootloader(libxl_ctx *ctx, &dom_console_slave_tty_path[0], sizeof(dom_console_slave_tty_path)); if (ret < 0) { - ret = ERROR_FAIL; - goto out; + goto out_close; } - dom_console_xs_path = libxl_sprintf(ctx, "%s/serial/0/tty", libxl_xs_get_dompath(ctx, domid)); - libxl_xs_write(ctx, XBT_NULL, dom_console_xs_path, "%s", dom_console_slave_tty_path); + dom_console_xs_path = libxl_sprintf(&gc, "%s/serial/0/tty", libxl_xs_get_dompath(&gc, domid)); + libxl_xs_write(&gc, XBT_NULL, dom_console_xs_path, "%s", dom_console_slave_tty_path); pid = fork_exec_bootloader(&bootloader_fd, (char *)info->u.pv.bootloader, args); if (pid < 0) { - ret = ERROR_FAIL; - goto out; + goto out_close; } while (1) { @@ -402,30 +399,27 @@ int libxl_run_bootloader(libxl_ctx *ctx, if (errno == EINTR) continue; - ret = ERROR_FAIL; - goto out; + goto out_close; } fcntl(fifo_fd, F_SETFL, O_NDELAY); - blout = bootloader_interact(ctx, xenconsoled_fd, bootloader_fd, fifo_fd); + blout = bootloader_interact(&gc, xenconsoled_fd, bootloader_fd, fifo_fd); if (blout == NULL) { - ret = ERROR_FAIL; - goto out; + goto out_close; } pid = waitpid(pid, &blrc, 0); if (pid == -1 || (pid > 0 && WIFEXITED(blrc) && WEXITSTATUS(blrc) != 0)) { - ret = ERROR_FAIL; - goto out; + goto out_close; } libxl_device_disk_local_detach(ctx, disk); parse_bootloader_result(ctx, info, blout); - ret = 0; -out: + rc = 0; +out_close: if (fifo_fd > -1) close(fifo_fd); if (bootloader_fd > -1) @@ -444,6 +438,8 @@ out: free(args); - return ret; +out: + libxl_free_all(&gc); + return rc; } diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index c81b85475b..905fe58c05 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -42,20 +42,24 @@ static const char *string_of_kinds[] = { int libxl_device_generic_add(libxl_ctx *ctx, libxl_device *device, char **bents, char **fents) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path_backend, *dom_path, *frontend_path, *backend_path; xs_transaction_t t; struct xs_permissions frontend_perms[2]; struct xs_permissions backend_perms[2]; + int rc; - if (!is_valid_device_kind(device->backend_kind) || !is_valid_device_kind(device->kind)) - return ERROR_INVAL; + if (!is_valid_device_kind(device->backend_kind) || !is_valid_device_kind(device->kind)) { + rc = ERROR_INVAL; + goto out; + } - dom_path_backend = libxl_xs_get_dompath(ctx, device->backend_domid); - dom_path = libxl_xs_get_dompath(ctx, device->domid); + dom_path_backend = libxl_xs_get_dompath(&gc, device->backend_domid); + dom_path = libxl_xs_get_dompath(&gc, device->domid); - frontend_path = libxl_sprintf(ctx, "%s/device/%s/%d", + frontend_path = libxl_sprintf(&gc, "%s/device/%s/%d", dom_path, string_of_kinds[device->kind], device->devid); - backend_path = libxl_sprintf(ctx, "%s/backend/%s/%u/%d", + backend_path = libxl_sprintf(&gc, "%s/backend/%s/%u/%d", dom_path_backend, string_of_kinds[device->backend_kind], device->domid, device->devid); frontend_perms[0].id = device->domid; @@ -81,12 +85,12 @@ retry_transaction: xs_mkdir(ctx->xsh, t, backend_path); xs_set_permissions(ctx->xsh, t, backend_path, backend_perms, ARRAY_SIZE(backend_perms)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/backend", frontend_path), backend_path, strlen(backend_path)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/frontend", backend_path), frontend_path, strlen(frontend_path)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/backend", frontend_path), backend_path, strlen(backend_path)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/frontend", backend_path), frontend_path, strlen(frontend_path)); /* and write frontend kvs and backend kvs */ - libxl_xs_writev(ctx, t, backend_path, bents); - libxl_xs_writev(ctx, t, frontend_path, fents); + libxl_xs_writev(&gc, t, backend_path, bents); + libxl_xs_writev(&gc, t, frontend_path, fents); if (!xs_transaction_end(ctx->xsh, t, 0)) { if (errno == EAGAIN) @@ -94,7 +98,10 @@ retry_transaction: else XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs transaction failed"); } - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } char *device_disk_string_of_phystype(libxl_disk_phystype phystype) @@ -221,35 +228,43 @@ int device_disk_dev_number(char *virtpath) int libxl_device_destroy(libxl_ctx *ctx, char *be_path, int force) { + libxl_gc gc = LIBXL_INIT_GC(ctx); xs_transaction_t t; - char *state_path = libxl_sprintf(ctx, "%s/state", be_path); - char *state = libxl_xs_read(ctx, XBT_NULL, state_path); + char *state_path = libxl_sprintf(&gc, "%s/state", be_path); + char *state = libxl_xs_read(&gc, XBT_NULL, state_path); + int rc = 0; + if (!state) - return 0; + goto out; if (atoi(state) != 4) { xs_rm(ctx->xsh, XBT_NULL, be_path); - return 0; + goto out; } retry_transaction: t = xs_transaction_start(ctx->xsh); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/online", be_path), "0", strlen("0")); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/online", be_path), "0", strlen("0")); xs_write(ctx->xsh, t, state_path, "5", strlen("5")); if (!xs_transaction_end(ctx->xsh, t, 0)) { if (errno == EAGAIN) goto retry_transaction; - else - return -1; + else { + rc = -1; + goto out; + } } if (!force) { xs_watch(ctx->xsh, state_path, be_path); - return 1; - } else - return 0; + rc = 1; + } +out: + libxl_free_all(&gc); + return rc; } int wait_for_dev_destroy(libxl_ctx *ctx, struct timeval *tv) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int nfds, rc; unsigned int n; fd_set rfds; @@ -262,57 +277,52 @@ int wait_for_dev_destroy(libxl_ctx *ctx, struct timeval *tv) if (select(nfds, &rfds, NULL, NULL, tv) > 0) { l1 = xs_read_watch(ctx->xsh, &n); if (l1 != NULL) { - char *state = libxl_xs_read(ctx, XBT_NULL, l1[XS_WATCH_PATH]); + char *state = libxl_xs_read(&gc, XBT_NULL, l1[XS_WATCH_PATH]); if (!state || atoi(state) == 6) { xs_unwatch(ctx->xsh, l1[0], l1[1]); xs_rm(ctx->xsh, XBT_NULL, l1[XS_WATCH_TOKEN]); XL_LOG(ctx, XL_LOG_DEBUG, "Destroyed device backend at %s", l1[XS_WATCH_TOKEN]); rc = 0; } - libxl_free(ctx, state); free(l1); } } + libxl_free_all(&gc); return rc; } int libxl_devices_destroy(libxl_ctx *ctx, uint32_t domid, int force) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path, *be_path, *fe_path; unsigned int num1, num2; char **l1 = NULL, **l2 = NULL; int i, j, n = 0, n_watches = 0; flexarray_t *toremove; - libxl_ctx clone; - - if (libxl_ctx_init(&clone, LIBXL_VERSION, ctx->lg)) { - return -1; - } toremove = flexarray_make(16, 1); - path = libxl_sprintf(&clone, "/local/domain/%d/device", domid); - l1 = libxl_xs_directory(&clone, XBT_NULL, path, &num1); + path = libxl_sprintf(&gc, "/local/domain/%d/device", domid); + l1 = libxl_xs_directory(&gc, XBT_NULL, path, &num1); if (!l1) { - XL_LOG(&clone, XL_LOG_ERROR, "%s is empty", path); - libxl_ctx_free(&clone); - return 0; + XL_LOG(ctx, XL_LOG_ERROR, "%s is empty", path); + goto out; } for (i = 0; i < num1; i++) { if (!strcmp("vfs", l1[i])) continue; - path = libxl_sprintf(&clone, "/local/domain/%d/device/%s", domid, l1[i]); - l2 = libxl_xs_directory(&clone, XBT_NULL, path, &num2); + path = libxl_sprintf(&gc, "/local/domain/%d/device/%s", domid, l1[i]); + l2 = libxl_xs_directory(&gc, XBT_NULL, path, &num2); if (!l2) continue; for (j = 0; j < num2; j++) { - fe_path = libxl_sprintf(&clone, "/local/domain/%d/device/%s/%s", domid, l1[i], l2[j]); - be_path = libxl_xs_read(&clone, XBT_NULL, libxl_sprintf(&clone, "%s/backend", fe_path)); + fe_path = libxl_sprintf(&gc, "/local/domain/%d/device/%s/%s", domid, l1[i], l2[j]); + be_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", fe_path)); if (be_path != NULL) { - if (libxl_device_destroy(&clone, be_path, force) > 0) + if (libxl_device_destroy(ctx, be_path, force) > 0) n_watches++; - flexarray_set(toremove, n++, libxl_dirname(&clone, be_path)); + flexarray_set(toremove, n++, libxl_dirname(&gc, be_path)); } else { - xs_rm(clone.xsh, XBT_NULL, path); + xs_rm(ctx->xsh, XBT_NULL, path); } } } @@ -326,7 +336,7 @@ int libxl_devices_destroy(libxl_ctx *ctx, uint32_t domid, int force) tv.tv_sec = LIBXL_DESTROY_TIMEOUT; tv.tv_usec = 0; while (n_watches > 0) { - if (wait_for_dev_destroy(&clone, &tv)) { + if (wait_for_dev_destroy(ctx, &tv)) { break; } else { n_watches--; @@ -335,46 +345,44 @@ int libxl_devices_destroy(libxl_ctx *ctx, uint32_t domid, int force) } for (i = 0; i < n; i++) { flexarray_get(toremove, i, (void**) &path); - xs_rm(clone.xsh, XBT_NULL, path); + xs_rm(ctx->xsh, XBT_NULL, path); } +out: flexarray_free(toremove); - libxl_ctx_free(&clone); + libxl_free_all(&gc); return 0; } int libxl_device_del(libxl_ctx *ctx, libxl_device *dev, int wait) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path_backend, *backend_path; int rc; - libxl_ctx clone; - - if (libxl_ctx_init(&clone, LIBXL_VERSION, ctx->lg)) { - return -1; - } /* Create strings */ - dom_path_backend = libxl_xs_get_dompath(&clone, dev->backend_domid); - backend_path = libxl_sprintf(&clone, "%s/backend/%s/%u/%d", + dom_path_backend = libxl_xs_get_dompath(&gc, dev->backend_domid); + backend_path = libxl_sprintf(&gc, "%s/backend/%s/%u/%d", dom_path_backend, string_of_kinds[dev->backend_kind], dev->domid, dev->devid); - libxl_free(&clone, dom_path_backend); - - rc = libxl_device_destroy(&clone, backend_path, !wait); + rc = libxl_device_destroy(ctx, backend_path, !wait); if (rc == -1) { - libxl_ctx_free(&clone); - return ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } if (wait) { struct timeval tv; tv.tv_sec = LIBXL_DESTROY_TIMEOUT; tv.tv_usec = 0; - (void)wait_for_dev_destroy(&clone, &tv); + (void)wait_for_dev_destroy(ctx, &tv); } - libxl_ctx_free(&clone); - return 0; + rc = 0; + +out: + libxl_free_all(&gc); + return rc; } int libxl_wait_for_device_model(libxl_ctx *ctx, @@ -385,6 +393,7 @@ int libxl_wait_for_device_model(libxl_ctx *ctx, void *userdata), void *check_callback_userdata) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path; char *p; unsigned int len; @@ -397,7 +406,7 @@ int libxl_wait_for_device_model(libxl_ctx *ctx, char **l = NULL; xsh = xs_daemon_open(); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); + path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d/state", domid); xs_watch(xsh, path, path); tv.tv_sec = LIBXL_DEVICE_MODEL_START_TIMEOUT; tv.tv_usec = 0; @@ -419,6 +428,7 @@ int libxl_wait_for_device_model(libxl_ctx *ctx, free(p); xs_unwatch(xsh, path, path); xs_daemon_close(xsh); + libxl_free_all(&gc); return rc; again: free(p); @@ -436,15 +446,17 @@ again: xs_unwatch(xsh, path, path); xs_daemon_close(xsh); XL_LOG(ctx, XL_LOG_ERROR, "Device Model not ready"); + libxl_free_all(&gc); return -1; } int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int watchdog = 100; unsigned int len; char *p; - char *path = libxl_sprintf(ctx, "%s/state", be_path); + char *path = libxl_sprintf(&gc, "%s/state", be_path); while (watchdog > 0) { p = xs_read(ctx->xsh, XBT_NULL, path, &len); @@ -467,6 +479,7 @@ int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state) } } XL_LOG(ctx, XL_LOG_ERROR, "Backend %s not ready", be_path); + libxl_free_all(&gc); return -1; } diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 2c1b5351e6..4fe018d7ef 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -86,6 +86,7 @@ int build_post(libxl_ctx *ctx, uint32_t domid, libxl_domain_build_info *info, libxl_domain_build_state *state, char **vms_ents, char **local_ents) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path, *vm_path; xs_transaction_t t; char **ents; @@ -95,44 +96,43 @@ int build_post(libxl_ctx *ctx, uint32_t domid, xc_cpuid_apply_policy(ctx->xch, domid); #endif - ents = libxl_calloc(ctx, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); + ents = libxl_calloc(&gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); ents[0] = "memory/static-max"; - ents[1] = libxl_sprintf(ctx, "%d", info->max_memkb); + ents[1] = libxl_sprintf(&gc, "%d", info->max_memkb); ents[2] = "memory/target"; - ents[3] = libxl_sprintf(ctx, "%d", info->target_memkb); + ents[3] = libxl_sprintf(&gc, "%d", info->target_memkb); ents[4] = "memory/videoram"; - ents[5] = libxl_sprintf(ctx, "%d", info->video_memkb); + ents[5] = libxl_sprintf(&gc, "%d", info->video_memkb); ents[6] = "domid"; - ents[7] = libxl_sprintf(ctx, "%d", domid); + ents[7] = libxl_sprintf(&gc, "%d", domid); ents[8] = "store/port"; - ents[9] = libxl_sprintf(ctx, "%"PRIu32, state->store_port); + ents[9] = libxl_sprintf(&gc, "%"PRIu32, state->store_port); ents[10] = "store/ring-ref"; - ents[11] = libxl_sprintf(ctx, "%lu", state->store_mfn); + ents[11] = libxl_sprintf(&gc, "%lu", state->store_mfn); for (i = 0; i < info->max_vcpus; i++) { - ents[12+(i*2)] = libxl_sprintf(ctx, "cpu/%d/availability", i); + ents[12+(i*2)] = libxl_sprintf(&gc, "cpu/%d/availability", i); ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i))) ? "offline" : "online"; } - dom_path = libxl_xs_get_dompath(ctx, domid); + dom_path = libxl_xs_get_dompath(&gc, domid); if (!dom_path) return ERROR_FAIL; - vm_path = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "%s/vm", dom_path), NULL); + vm_path = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, "%s/vm", dom_path), NULL); retry_transaction: t = xs_transaction_start(ctx->xsh); - libxl_xs_writev(ctx, t, dom_path, ents); - libxl_xs_writev(ctx, t, dom_path, local_ents); - libxl_xs_writev(ctx, t, vm_path, vms_ents); + libxl_xs_writev(&gc, t, dom_path, ents); + libxl_xs_writev(&gc, t, dom_path, local_ents); + libxl_xs_writev(&gc, t, vm_path, vms_ents); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; xs_introduce_domain(ctx->xsh, domid, state->store_mfn, state->store_port); free(vm_path); - libxl_free(ctx, ents); - libxl_free(ctx, dom_path); + libxl_free_all(&gc); return 0; } @@ -218,30 +218,35 @@ out: int build_hvm(libxl_ctx *ctx, uint32_t domid, libxl_domain_build_info *info, libxl_domain_build_state *state) { - int ret; + libxl_gc gc = LIBXL_INIT_GC(ctx); + int ret, rc = ERROR_INVAL; if (info->kernel.mapped) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "build_hvm kernel cannot be mmapped"); - return ERROR_INVAL; + goto out; } + rc = ERROR_FAIL; ret = xc_hvm_build_target_mem( ctx->xch, domid, (info->max_memkb - info->video_memkb) / 1024, (info->target_memkb - info->video_memkb) / 1024, - libxl_abs_path(ctx, (char *)info->kernel.path, + libxl_abs_path(&gc, (char *)info->kernel.path, libxl_xenfirmwaredir_path())); if (ret) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "hvm building failed"); - return ERROR_FAIL; + goto out; } ret = hvm_build_set_params(ctx->xch, domid, info, state->store_port, &state->store_mfn, state->console_port, &state->console_mfn); if (ret) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "hvm build set params failed"); - return ERROR_FAIL; + goto out; } + rc = 0; +out: + libxl_free_all(&gc); return 0; } @@ -263,7 +268,7 @@ int restore_common(libxl_ctx *ctx, uint32_t domid, } struct suspendinfo { - libxl_ctx *ctx; + libxl_gc *gc; int xce; /* event channel handle */ int suspend_eventchn; int domid; @@ -295,39 +300,40 @@ static int core_suspend_callback(void *data) int ret; char *path, *state = "suspend"; int watchdog = 60; + libxl_ctx *ctx = libxl_gc_owner(si->gc); if (si->hvm) - xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, &s_state); + xc_get_hvm_param(ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, &s_state); if ((s_state == 0) && (si->suspend_eventchn >= 0)) { ret = xc_evtchn_notify(si->xce, si->suspend_eventchn); if (ret < 0) { - XL_LOG(si->ctx, XL_LOG_ERROR, "xc_evtchn_notify failed ret=%d", ret); + XL_LOG(ctx, XL_LOG_ERROR, "xc_evtchn_notify failed ret=%d", ret); return 0; } - ret = xc_await_suspend(si->ctx->xch, si->xce, si->suspend_eventchn); + ret = xc_await_suspend(ctx->xch, si->xce, si->suspend_eventchn); if (ret < 0) { - XL_LOG(si->ctx, XL_LOG_ERROR, "xc_await_suspend failed ret=%d", ret); + XL_LOG(ctx, XL_LOG_ERROR, "xc_await_suspend failed ret=%d", ret); return 0; } return 1; } - path = libxl_sprintf(si->ctx, "%s/control/shutdown", libxl_xs_get_dompath(si->ctx, si->domid)); - libxl_xs_write(si->ctx, XBT_NULL, path, "suspend"); + path = libxl_sprintf(si->gc, "%s/control/shutdown", libxl_xs_get_dompath(si->gc, si->domid)); + libxl_xs_write(si->gc, XBT_NULL, path, "suspend"); if (si->hvm) { unsigned long hvm_pvdrv, hvm_s_state; - xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_CALLBACK_IRQ, &hvm_pvdrv); - xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, &hvm_s_state); + xc_get_hvm_param(ctx->xch, si->domid, HVM_PARAM_CALLBACK_IRQ, &hvm_pvdrv); + xc_get_hvm_param(ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, &hvm_s_state); if (!hvm_pvdrv || hvm_s_state) { - XL_LOG(si->ctx, XL_LOG_DEBUG, "Calling xc_domain_shutdown on the domain"); - xc_domain_shutdown(si->ctx->xch, si->domid, SHUTDOWN_suspend); + XL_LOG(ctx, XL_LOG_DEBUG, "Calling xc_domain_shutdown on the domain"); + xc_domain_shutdown(ctx->xch, si->domid, SHUTDOWN_suspend); } } - XL_LOG(si->ctx, XL_LOG_DEBUG, "wait for the guest to suspend"); + XL_LOG(ctx, XL_LOG_DEBUG, "wait for the guest to suspend"); while (!strcmp(state, "suspend") && watchdog > 0) { xc_domaininfo_t info; usleep(100000); - ret = xc_domain_getinfolist(si->ctx->xch, si->domid, 1, &info); + ret = xc_domain_getinfolist(ctx->xch, si->domid, 1, &info); if (ret == 1 && info.domain == si->domid && info.flags & XEN_DOMINF_shutdown) { int shutdown_reason; @@ -335,12 +341,12 @@ static int core_suspend_callback(void *data) if (shutdown_reason == SHUTDOWN_suspend) return 1; } - state = libxl_xs_read(si->ctx, XBT_NULL, path); + state = libxl_xs_read(si->gc, XBT_NULL, path); watchdog--; } if (!strcmp(state, "suspend")) { - XL_LOG(si->ctx, XL_LOG_ERROR, "guest didn't suspend in time"); - libxl_xs_write(si->ctx, XBT_NULL, path, ""); + XL_LOG(ctx, XL_LOG_ERROR, "guest didn't suspend in time"); + libxl_xs_write(si->gc, XBT_NULL, path, ""); } return 1; } @@ -348,10 +354,12 @@ static int core_suspend_callback(void *data) int core_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int hvm, int live, int debug) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int flags; int port; struct save_callbacks callbacks; struct suspendinfo si; + int rc = ERROR_FAIL; flags = (live) ? XCFLAGS_LIVE : 0 | (debug) ? XCFLAGS_DEBUG : 0 @@ -360,12 +368,12 @@ int core_suspend(libxl_ctx *ctx, uint32_t domid, int fd, si.domid = domid; si.flags = flags; si.hvm = hvm; - si.ctx = ctx; + si.gc = &gc; si.suspend_eventchn = -1; si.xce = xc_evtchn_open(); if (si.xce < 0) - return ERROR_FAIL; + goto out; if (si.xce > 0) { port = xs_suspend_evtchn_port(si.domid); @@ -373,7 +381,7 @@ int core_suspend(libxl_ctx *ctx, uint32_t domid, int fd, if (port < 0) { XL_LOG(ctx, XL_LOG_WARNING, "Failed to get the suspend evtchn port"); } else { - si.suspend_eventchn = xc_suspend_evtchn_init(si.ctx->xch, si.xce, si.domid, port); + si.suspend_eventchn = xc_suspend_evtchn_init(ctx->xch, si.xce, si.domid, port); if (si.suspend_eventchn < 0) XL_LOG(ctx, XL_LOG_WARNING, "Suspend event channel initialization failed"); @@ -389,21 +397,24 @@ int core_suspend(libxl_ctx *ctx, uint32_t domid, int fd, &core_suspend_switch_qemu_logdirty); if (si.suspend_eventchn > 0) - xc_suspend_evtchn_release(si.ctx->xch, si.xce, domid, si.suspend_eventchn); + xc_suspend_evtchn_release(ctx->xch, si.xce, domid, si.suspend_eventchn); if (si.xce > 0) xc_evtchn_close(si.xce); - return 0; + rc = 0; +out: + return rc; } int save_device_model(libxl_ctx *ctx, uint32_t domid, int fd) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int fd2, c; char buf[1024]; - char *filename = libxl_sprintf(ctx, "/var/lib/xen/qemu-save.%d", domid); + char *filename = libxl_sprintf(&gc, "/var/lib/xen/qemu-save.%d", domid); XL_LOG(ctx, XL_LOG_DEBUG, "Saving device model state to %s", filename); - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "save"); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/0/device-model/%d/command", domid), "save"); libxl_wait_for_device_model(ctx, domid, "paused", NULL, NULL); c = libxl_write_exactly(ctx, fd, QEMU_SIGNATURE, strlen(QEMU_SIGNATURE), @@ -415,27 +426,42 @@ int save_device_model(libxl_ctx *ctx, uint32_t domid, int fd) if (c < 0) { if (errno == EINTR) continue; + libxl_free_all(&gc); return errno; } c = libxl_write_exactly( ctx, fd, buf, c, "saved-state file", "qemu state"); - if (c) + if (c) { + libxl_free_all(&gc); return c; + } } close(fd2); unlink(filename); + libxl_free_all(&gc); return 0; } -char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid) { - char *s = string_of_uuid(ctx, uuid); - if (!s) XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate for uuid"); - return s; +char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *s = string_of_uuid(&gc, uuid); + char *ret; + if (!s) { + XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate for uuid"); + ret = NULL; + }else{ + ret = strdup(s); + } + libxl_free_all(&gc); + return ret; } -static const char *userdata_path(libxl_ctx *ctx, uint32_t domid, +static const char *userdata_path(libxl_gc *gc, uint32_t domid, const char *userdata_userid, - const char *wh) { + const char *wh) +{ + libxl_ctx *ctx = libxl_gc_owner(gc); char *path, *uuid_string; libxl_dominfo info; int rc; @@ -446,9 +472,9 @@ static const char *userdata_path(libxl_ctx *ctx, uint32_t domid, " for domain %"PRIu32, domid); return NULL; } - uuid_string = string_of_uuid(ctx, info.uuid); + uuid_string = string_of_uuid(gc, info.uuid); - path = libxl_sprintf(ctx, "/var/lib/xen/" + path = libxl_sprintf(gc, "/var/lib/xen/" "userdata-%s.%s.%s", wh, uuid_string, userdata_userid); if (!path) @@ -467,94 +493,132 @@ static int userdata_delete(libxl_ctx *ctx, const char *path) { return 0; } -void libxl__userdata_destroyall(libxl_ctx *ctx, uint32_t domid) { +void libxl__userdata_destroyall(libxl_ctx *ctx, uint32_t domid) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); const char *pattern; glob_t gl; int r, i; - pattern = userdata_path(ctx, domid, "*", "?"); - if (!pattern) return; + pattern = userdata_path(&gc, domid, "*", "?"); + if (!pattern) + goto out; gl.gl_pathc = 0; gl.gl_pathv = 0; gl.gl_offs = 0; r = glob(pattern, GLOB_ERR|GLOB_NOSORT|GLOB_MARK, 0, &gl); - if (r == GLOB_NOMATCH) return; - if (r) XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "glob failed for %s", pattern); + if (r == GLOB_NOMATCH) + goto out; + if (r) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "glob failed for %s", pattern); for (i=0; i=0) close(fd); errno = e; - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot write %s for %s", + if ( rc ) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot write %s for %s", newfilename, filename); - return ERROR_FAIL; +out: + libxl_free_all(&gc); + return rc; } int libxl_userdata_retrieve(libxl_ctx *ctx, uint32_t domid, const char *userdata_userid, - uint8_t **data_r, int *datalen_r) { + uint8_t **data_r, int *datalen_r) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); const char *filename; - int e; + int e, rc; int datalen = 0; void *data = 0; - filename = userdata_path(ctx, domid, userdata_userid, "d"); - if (!filename) return ERROR_NOMEM; + filename = userdata_path(&gc, domid, userdata_userid, "d"); + if (!filename) { + rc = ERROR_NOMEM; + goto out; + } e = libxl_read_file_contents(ctx, filename, data_r ? &data : 0, &datalen); if (!e && !datalen) { XL_LOG(ctx, XL_LOG_ERROR, "userdata file %s is empty", filename); if (data_r) assert(!*data_r); - return ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } if (data_r) *data_r = data; if (datalen_r) *datalen_r = datalen; - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } diff --git a/tools/libxl/libxl_exec.c b/tools/libxl/libxl_exec.c index c488e38975..5210c4f98a 100644 --- a/tools/libxl/libxl_exec.c +++ b/tools/libxl/libxl_exec.c @@ -100,7 +100,7 @@ int libxl_spawn_spawn(libxl_ctx *ctx, libxl_spawn_starting *for_spawn = starting->for_spawn; if (for_spawn) { - for_spawn->what = libxl_strdup(ctx, what); + for_spawn->what = strdup(what); if (!for_spawn->what) return ERROR_NOMEM; } @@ -140,10 +140,12 @@ static void report_spawn_intermediate_status(libxl_ctx *ctx, int status) { if (!WIFEXITED(status)) { + char *intermediate_what; /* intermediate process did the logging itself if it exited */ - char *intermediate_what = libxl_sprintf(ctx, - "%s intermediate process (startup monitor)", - for_spawn->what); + if ( asprintf(&intermediate_what, + "%s intermediate process (startup monitor)", + for_spawn->what) < 0 ) + intermediate_what = "intermediate process (startup monitor)"; libxl_report_child_exitstatus(ctx, XL_LOG_ERROR, intermediate_what, for_spawn->intermediate, status); } diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c index 22595f1578..2d5ad9a033 100644 --- a/tools/libxl/libxl_internal.c +++ b/tools/libxl/libxl_internal.c @@ -28,7 +28,7 @@ int libxl_error_set(libxl_ctx *ctx, int code) return 0; } -int libxl_ptr_add(libxl_ctx *ctx, void *ptr) +int libxl_ptr_add(libxl_gc *gc, void *ptr) { int i; void **re; @@ -37,29 +37,29 @@ int libxl_ptr_add(libxl_ctx *ctx, void *ptr) return 0; /* fast case: we have space in the array for storing the pointer */ - for (i = 0; i < ctx->alloc_maxsize; i++) { - if (!ctx->alloc_ptrs[i]) { - ctx->alloc_ptrs[i] = ptr; + for (i = 0; i < gc->alloc_maxsize; i++) { + if (!gc->alloc_ptrs[i]) { + gc->alloc_ptrs[i] = ptr; return 0; } } /* realloc alloc_ptrs manually with calloc/free/replace */ - re = calloc(ctx->alloc_maxsize + 25, sizeof(void *)); + re = calloc(gc->alloc_maxsize + 25, sizeof(void *)); if (!re) return -1; - for (i = 0; i < ctx->alloc_maxsize; i++) - re[i] = ctx->alloc_ptrs[i]; + for (i = 0; i < gc->alloc_maxsize; i++) + re[i] = gc->alloc_ptrs[i]; /* assign the next pointer */ re[i] = ptr; /* replace the old alloc_ptr */ - free(ctx->alloc_ptrs); - ctx->alloc_ptrs = re; - ctx->alloc_maxsize += 25; + free(gc->alloc_ptrs); + gc->alloc_ptrs = re; + gc->alloc_maxsize += 25; return 0; } -void libxl_free(libxl_ctx *ctx, void *ptr) +void libxl_free(libxl_gc *gc, void *ptr) { int i; @@ -67,9 +67,9 @@ void libxl_free(libxl_ctx *ctx, void *ptr) return; /* remove the pointer from the tracked ptrs */ - for (i = 0; i < ctx->alloc_maxsize; i++) { - if (ctx->alloc_ptrs[i] == ptr) { - ctx->alloc_ptrs[i] = NULL; + for (i = 0; i < gc->alloc_maxsize; i++) { + if (gc->alloc_ptrs[i] == ptr) { + gc->alloc_ptrs[i] = NULL; free(ptr); return; } @@ -78,43 +78,44 @@ void libxl_free(libxl_ctx *ctx, void *ptr) abort(); } -void libxl_free_all(libxl_ctx *ctx) +void libxl_free_all(libxl_gc *gc) { void *ptr; int i; - for (i = 0; i < ctx->alloc_maxsize; i++) { - ptr = ctx->alloc_ptrs[i]; - ctx->alloc_ptrs[i] = NULL; + for (i = 0; i < gc->alloc_maxsize; i++) { + ptr = gc->alloc_ptrs[i]; + gc->alloc_ptrs[i] = NULL; free(ptr); } + free(gc->alloc_ptrs); } -void *libxl_zalloc(libxl_ctx *ctx, int bytes) +void *libxl_zalloc(libxl_gc *gc, int bytes) { void *ptr = calloc(bytes, 1); if (!ptr) { - libxl_error_set(ctx, ENOMEM); + libxl_error_set(libxl_gc_owner(gc), ENOMEM); return NULL; } - libxl_ptr_add(ctx, ptr); + libxl_ptr_add(gc, ptr); return ptr; } -void *libxl_calloc(libxl_ctx *ctx, size_t nmemb, size_t size) +void *libxl_calloc(libxl_gc *gc, size_t nmemb, size_t size) { void *ptr = calloc(nmemb, size); if (!ptr) { - libxl_error_set(ctx, ENOMEM); + libxl_error_set(libxl_gc_owner(gc), ENOMEM); return NULL; } - libxl_ptr_add(ctx, ptr); + libxl_ptr_add(gc, ptr); return ptr; } -char *libxl_sprintf(libxl_ctx *ctx, const char *fmt, ...) +char *libxl_sprintf(libxl_gc *gc, const char *fmt, ...) { char *s; va_list ap; @@ -128,7 +129,7 @@ char *libxl_sprintf(libxl_ctx *ctx, const char *fmt, ...) return NULL; } - s = libxl_zalloc(ctx, ret + 1); + s = libxl_zalloc(gc, ret + 1); if (s) { va_start(ap, fmt); ret = vsnprintf(s, ret + 1, fmt, ap); @@ -137,20 +138,20 @@ char *libxl_sprintf(libxl_ctx *ctx, const char *fmt, ...) return s; } -char *libxl_strdup(libxl_ctx *ctx, const char *c) +char *libxl_strdup(libxl_gc *gc, const char *c) { char *s = strdup(c); if (s) - libxl_ptr_add(ctx, s); + libxl_ptr_add(gc, s); return s; } -char *libxl_dirname(libxl_ctx *ctx, const char *s) +char *libxl_dirname(libxl_gc *gc, const char *s) { char *c; - char *ptr = libxl_strdup(ctx, s); + char *ptr = libxl_strdup(gc, s); c = strrchr(ptr, '/'); if (!c) @@ -196,10 +197,10 @@ void xl_log(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval, va_end(ap); } -char *libxl_abs_path(libxl_ctx *ctx, char *s, const char *path) +char *libxl_abs_path(libxl_gc *gc, char *s, const char *path) { if (!s || s[0] == '/') return s; - return libxl_sprintf(ctx, "%s/%s", path, s); + return libxl_sprintf(gc, "%s/%s", path, s); } diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 529c883a72..fecb009e7c 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -114,24 +114,37 @@ typedef struct { _hidden int xs_writev(struct xs_handle *xsh, xs_transaction_t t, char *dir, char *kvs[]); +typedef struct { + /* mini-GC */ + int alloc_maxsize; + void **alloc_ptrs; + libxl_ctx *owner; +} libxl_gc; + +#define LIBXL_INIT_GC(ctx) (libxl_gc){ .alloc_maxsize = 0, .alloc_ptrs = 0, .owner = ctx } +static inline libxl_ctx *libxl_gc_owner(libxl_gc *gc) +{ + return gc->owner; +} + /* memory allocation tracking/helpers */ -_hidden int libxl_ptr_add(libxl_ctx *ctx, void *ptr); -_hidden void libxl_free(libxl_ctx *ctx, void *ptr); -_hidden void libxl_free_all(libxl_ctx *ctx); -_hidden void *libxl_zalloc(libxl_ctx *ctx, int bytes); -_hidden void *libxl_calloc(libxl_ctx *ctx, size_t nmemb, size_t size); -_hidden char *libxl_sprintf(libxl_ctx *ctx, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); -_hidden char *libxl_strdup(libxl_ctx *ctx, const char *c); -_hidden char *libxl_dirname(libxl_ctx *ctx, const char *s); - -_hidden char **libxl_xs_kvs_of_flexarray(libxl_ctx *ctx, flexarray_t *array, int length); -_hidden int libxl_xs_writev(libxl_ctx *ctx, xs_transaction_t t, +_hidden int libxl_ptr_add(libxl_gc *gc, void *ptr); +_hidden void libxl_free(libxl_gc *gc, void *ptr); +_hidden void libxl_free_all(libxl_gc *gc); +_hidden void *libxl_zalloc(libxl_gc *gc, int bytes); +_hidden void *libxl_calloc(libxl_gc *gc, size_t nmemb, size_t size); +_hidden char *libxl_sprintf(libxl_gc *gc, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); +_hidden char *libxl_strdup(libxl_gc *gc, const char *c); +_hidden char *libxl_dirname(libxl_gc *gc, const char *s); + +_hidden char **libxl_xs_kvs_of_flexarray(libxl_gc *gc, flexarray_t *array, int length); +_hidden int libxl_xs_writev(libxl_gc *gc, xs_transaction_t t, char *dir, char **kvs); -_hidden int libxl_xs_write(libxl_ctx *ctx, xs_transaction_t t, +_hidden int libxl_xs_write(libxl_gc *gc, xs_transaction_t t, char *path, char *fmt, ...) PRINTF_ATTRIBUTE(4, 5); -_hidden char *libxl_xs_get_dompath(libxl_ctx *ctx, uint32_t domid); // logs errs -_hidden char *libxl_xs_read(libxl_ctx *ctx, xs_transaction_t t, char *path); -_hidden char **libxl_xs_directory(libxl_ctx *ctx, xs_transaction_t t, char *path, unsigned int *nb); +_hidden char *libxl_xs_get_dompath(libxl_gc *gc, uint32_t domid); // logs errs +_hidden char *libxl_xs_read(libxl_gc *gc, xs_transaction_t t, char *path); +_hidden char **libxl_xs_directory(libxl_gc *gc, xs_transaction_t t, char *path, unsigned int *nb); /* from xl_dom */ _hidden int is_hvm(libxl_ctx *ctx, uint32_t domid); @@ -175,8 +188,6 @@ _hidden int libxl_wait_for_device_model(libxl_ctx *ctx, void *userdata), void *check_callback_userdata); _hidden int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state); -_hidden int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int bus, - unsigned int dev, unsigned int func); /* from xenguest (helper */ _hidden int hvm_build_set_params(xc_interface *handle, uint32_t domid, @@ -225,18 +236,17 @@ _hidden int libxl_spawn_check(libxl_ctx *ctx, /* low-level stuff, for synchronous subprocesses etc. */ _hidden void libxl_exec(int stdinfd, int stdoutfd, int stderrfd, char *arg0, char **args); // logs errors, never returns -_hidden void libxl_log_child_exitstatus(libxl_ctx *ctx, +_hidden void libxl_log_child_exitstatus(libxl_gc *gc, const char *what, pid_t pid, int status); -_hidden char *libxl_abs_path(libxl_ctx *ctx, char *s, const char *path); +_hidden char *libxl_abs_path(libxl_gc *gc, char *s, const char *path); #define XL_LOG_DEBUG XTL_DEBUG #define XL_LOG_INFO XTL_INFO #define XL_LOG_WARNING XTL_WARN #define XL_LOG_ERROR XTL_ERROR -_hidden char *_libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid); -_hidden char *_libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid); +_hidden char *_libxl_domid_to_name(libxl_gc *gc, uint32_t domid); +_hidden char *_libxl_poolid_to_name(libxl_gc *gc, uint32_t poolid); #endif - diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c index 9fc605a261..f32db3b0e1 100644 --- a/tools/libxl/libxl_pci.c +++ b/tools/libxl/libxl_pci.c @@ -195,8 +195,9 @@ parse_error: return ERROR_INVAL; } -static int libxl_create_pci_backend(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev, int num) +static int libxl_create_pci_backend(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev, int num) { + libxl_ctx *ctx = libxl_gc_owner(gc); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; @@ -222,56 +223,57 @@ static int libxl_create_pci_backend(libxl_ctx *ctx, uint32_t domid, libxl_device device.kind = DEVICE_PCI; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", domid)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 1)); flexarray_set(back, boffset++, "domain"); - flexarray_set(back, boffset++, _libxl_domid_to_name(ctx, domid)); + flexarray_set(back, boffset++, _libxl_domid_to_name(gc, domid)); for (i = 0; i < num; i++) { - flexarray_set(back, boffset++, libxl_sprintf(ctx, "key-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "key-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "dev-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); if (pcidev->vdevfn) { - flexarray_set(back, boffset++, libxl_sprintf(ctx, "vdevfn-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x", pcidev->vdevfn)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "vdevfn-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%x", pcidev->vdevfn)); } - flexarray_set(back, boffset++, libxl_sprintf(ctx, "opts-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "state-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "opts-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "state-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 1)); } flexarray_set(back, boffset++, "num_devs"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", num)); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 0)); + flexarray_set(front, foffset++, libxl_sprintf(gc, "%d", 0)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(gc, "%d", 1)); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(gc, back, boffset), + libxl_xs_kvs_of_flexarray(gc, front, foffset)); flexarray_free(back); flexarray_free(front); return 0; } -static int libxl_device_pci_add_xenstore(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) +static int libxl_device_pci_add_xenstore(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev) { + libxl_ctx *ctx = libxl_gc_owner(gc); flexarray_t *back; char *num_devs, *be_path; int num = 0; unsigned int boffset = 0; xs_transaction_t t; - be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", libxl_xs_get_dompath(ctx, 0), domid); - num_devs = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/num_devs", be_path)); + be_path = libxl_sprintf(gc, "%s/backend/pci/%d/0", libxl_xs_get_dompath(gc, 0), domid); + num_devs = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, "%s/num_devs", be_path)); if (!num_devs) - return libxl_create_pci_backend(ctx, domid, pcidev, 1); + return libxl_create_pci_backend(gc, domid, pcidev, 1); if (!is_hvm(ctx, domid)) { if (libxl_wait_for_backend(ctx, be_path, "4") < 0) @@ -284,27 +286,27 @@ static int libxl_device_pci_add_xenstore(libxl_ctx *ctx, uint32_t domid, libxl_d XL_LOG(ctx, XL_LOG_DEBUG, "Adding new pci device to xenstore"); num = atoi(num_devs); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "key-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "key-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "dev-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); if (pcidev->vdevfn) { - flexarray_set(back, boffset++, libxl_sprintf(ctx, "vdevfn-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x", pcidev->vdevfn)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "vdevfn-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%x", pcidev->vdevfn)); } - flexarray_set(back, boffset++, libxl_sprintf(ctx, "opts-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "state-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "opts-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "state-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 1)); flexarray_set(back, boffset++, "num_devs"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", num + 1)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", num + 1)); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 7)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 7)); retry_transaction: t = xs_transaction_start(ctx->xsh); - libxl_xs_writev(ctx, t, be_path, - libxl_xs_kvs_of_flexarray(ctx, back, boffset)); + libxl_xs_writev(gc, t, be_path, + libxl_xs_kvs_of_flexarray(gc, back, boffset)); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; @@ -313,16 +315,17 @@ retry_transaction: return 0; } -static int libxl_device_pci_remove_xenstore(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) +static int libxl_device_pci_remove_xenstore(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *be_path, *num_devs_path, *num_devs, *xsdev, *tmp, *tmppath; int num, i, j; xs_transaction_t t; unsigned int domain = 0, bus = 0, dev = 0, func = 0; - be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", libxl_xs_get_dompath(ctx, 0), domid); - num_devs_path = libxl_sprintf(ctx, "%s/num_devs", be_path); - num_devs = libxl_xs_read(ctx, XBT_NULL, num_devs_path); + be_path = libxl_sprintf(gc, "%s/backend/pci/%d/0", libxl_xs_get_dompath(gc, 0), domid); + num_devs_path = libxl_sprintf(gc, "%s/num_devs", be_path); + num_devs = libxl_xs_read(gc, XBT_NULL, num_devs_path); if (!num_devs) return ERROR_INVAL; num = atoi(num_devs); @@ -335,7 +338,7 @@ static int libxl_device_pci_remove_xenstore(libxl_ctx *ctx, uint32_t domid, libx } for (i = 0; i < num; i++) { - xsdev = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev-%d", be_path, i)); + xsdev = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, "%s/dev-%d", be_path, i)); sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func); if (domain == pcidev->domain && bus == pcidev->bus && pcidev->dev == dev && pcidev->func == func) { @@ -349,8 +352,8 @@ static int libxl_device_pci_remove_xenstore(libxl_ctx *ctx, uint32_t domid, libx retry_transaction: t = xs_transaction_start(ctx->xsh); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, i), "5", strlen("5")); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state", be_path), "7", strlen("7")); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/state-%d", be_path, i), "5", strlen("5")); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/state", be_path), "7", strlen("7")); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; @@ -364,42 +367,42 @@ retry_transaction: retry_transaction2: t = xs_transaction_start(ctx->xsh); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/key-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/dev-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdev-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/opts-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, i)); - libxl_xs_write(ctx, t, num_devs_path, "%d", num - 1); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/state-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/key-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/dev-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/vdev-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/opts-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/vdevfn-%d", be_path, i)); + libxl_xs_write(gc, t, num_devs_path, "%d", num - 1); for (j = i + 1; j < num; j++) { - tmppath = libxl_sprintf(ctx, "%s/state-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, j - 1), tmp, strlen(tmp)); + tmppath = libxl_sprintf(gc, "%s/state-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/state-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); - tmppath = libxl_sprintf(ctx, "%s/dev-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/dev-%d", be_path, j - 1), tmp, strlen(tmp)); + tmppath = libxl_sprintf(gc, "%s/dev-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/dev-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); - tmppath = libxl_sprintf(ctx, "%s/key-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/key-%d", be_path, j - 1), tmp, strlen(tmp)); + tmppath = libxl_sprintf(gc, "%s/key-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/key-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); - tmppath = libxl_sprintf(ctx, "%s/vdev-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); + tmppath = libxl_sprintf(gc, "%s/vdev-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); if (tmp) { - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdev-%d", be_path, j - 1), tmp, strlen(tmp)); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/vdev-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); } - tmppath = libxl_sprintf(ctx, "%s/opts-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); + tmppath = libxl_sprintf(gc, "%s/opts-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); if (tmp) { - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/opts-%d", be_path, j - 1), tmp, strlen(tmp)); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/opts-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); } - tmppath = libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); + tmppath = libxl_sprintf(gc, "%s/vdevfn-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); if (tmp) { - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp)); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); } } @@ -408,7 +411,7 @@ retry_transaction2: goto retry_transaction2; if (num == 1) { - char *fe_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend", be_path)); + char *fe_path = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, "%s/frontend", be_path)); libxl_device_destroy(ctx, be_path, 1); xs_rm(ctx->xsh, XBT_NULL, be_path); xs_rm(ctx->xsh, XBT_NULL, fe_path); @@ -418,7 +421,7 @@ retry_transaction2: return 0; } -static int get_all_assigned_devices(libxl_ctx *ctx, libxl_device_pci **list, int *num) +static int get_all_assigned_devices(libxl_gc *gc, libxl_device_pci **list, int *num) { libxl_device_pci *pcidevs = NULL; char **domlist; @@ -427,21 +430,21 @@ static int get_all_assigned_devices(libxl_ctx *ctx, libxl_device_pci **list, int *list = NULL; *num = 0; - domlist = libxl_xs_directory(ctx, XBT_NULL, "/local/domain", &nd); + domlist = libxl_xs_directory(gc, XBT_NULL, "/local/domain", &nd); for(i = 0; i < nd; i++) { char *path, *num_devs; - path = libxl_sprintf(ctx, "/local/domain/0/backend/pci/%s/0/num_devs", domlist[i]); - num_devs = libxl_xs_read(ctx, XBT_NULL, path); + path = libxl_sprintf(gc, "/local/domain/0/backend/pci/%s/0/num_devs", domlist[i]); + num_devs = libxl_xs_read(gc, XBT_NULL, path); if ( num_devs ) { int ndev = atoi(num_devs), j; char *devpath, *bdf; - pcidevs = calloc(sizeof(*pcidevs), ndev); + pcidevs = libxl_calloc(gc, sizeof(*pcidevs), ndev); for(j = (pcidevs) ? 0 : ndev; j < ndev; j++) { - devpath = libxl_sprintf(ctx, "/local/domain/0/backend/pci/%s/0/dev-%u", + devpath = libxl_sprintf(gc, "/local/domain/0/backend/pci/%s/0/dev-%u", domlist[i], j); - bdf = libxl_xs_read(ctx, XBT_NULL, devpath); + bdf = libxl_xs_read(gc, XBT_NULL, devpath); if ( bdf ) { unsigned dom, bus, dev, func; if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 ) @@ -486,6 +489,7 @@ static int is_assigned(libxl_device_pci *assigned, int num_assigned, int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, int *num) { + libxl_gc gc = LIBXL_INIT_GC(ctx); libxl_device_pci *pcidevs = NULL, *new, *assigned; struct dirent *de; DIR *dir; @@ -494,7 +498,7 @@ int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, in *num = 0; *list = NULL; - rc = get_all_assigned_devices(ctx, &assigned, &num_assigned); + rc = get_all_assigned_devices(&gc, &assigned, &num_assigned); if ( rc ) return rc; @@ -505,7 +509,7 @@ int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, in }else{ XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", SYSFS_PCIBACK_DRIVER); } - free(assigned); + libxl_free_all(&gc); return ERROR_FAIL; } @@ -530,8 +534,8 @@ int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, in } closedir(dir); - free(assigned); *list = pcidevs; + libxl_free_all(&gc); return 0; } @@ -540,8 +544,9 @@ int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, in * driver. It also initialises a bit-mask of which function numbers are present * on that device. */ -static int pci_multifunction_check(libxl_ctx *ctx, libxl_device_pci *pcidev, unsigned int *func_mask) +static int pci_multifunction_check(libxl_gc *gc, libxl_device_pci *pcidev, unsigned int *func_mask) { + libxl_ctx *ctx = libxl_gc_owner(gc); struct dirent *de; DIR *dir; @@ -567,7 +572,7 @@ static int pci_multifunction_check(libxl_ctx *ctx, libxl_device_pci *pcidev, uns if ( pcidev->dev != dev ) continue; - path = libxl_sprintf(ctx, "%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func); + path = libxl_sprintf(gc, "%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func); if ( lstat(path, &st) ) { if ( errno == ENOENT ) XL_LOG(ctx, XL_LOG_ERROR, PCI_BDF " is not assigned to pciback driver", @@ -598,8 +603,9 @@ static int pci_ins_check(libxl_ctx *ctx, uint32_t domid, const char *state, void return 1; } -static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) +static int do_pci_add(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *path; char *state, *vdevfn; int rc, hvm; @@ -609,21 +615,21 @@ static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) if (libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL) < 0) { return ERROR_FAIL; } - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); - state = libxl_xs_read(ctx, XBT_NULL, path); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", domid); + state = libxl_xs_read(gc, XBT_NULL, path); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid); if (pcidev->vdevfn) - libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF_VDEVFN, pcidev->domain, + libxl_xs_write(gc, XBT_NULL, path, PCI_BDF_VDEVFN, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func, pcidev->vdevfn); else - libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain, + libxl_xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/command", domid); xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins")); rc = libxl_wait_for_device_model(ctx, domid, NULL, pci_ins_check, state); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid); - vdevfn = libxl_xs_read(ctx, XBT_NULL, path); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid); + vdevfn = libxl_xs_read(gc, XBT_NULL, path); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", domid); if ( rc < 0 ) XL_LOG(ctx, XL_LOG_ERROR, "qemu refused to add device: %s", vdevfn); else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 ) @@ -632,7 +638,7 @@ static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) if ( rc ) return ERROR_FAIL; } else { - char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, + char *sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); FILE *f = fopen(sysfs_path, "r"); unsigned long long start = 0, end = 0, flags = 0, size = 0; @@ -667,7 +673,7 @@ static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) } } fclose(f); - sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, + sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); f = fopen(sysfs_path, "r"); if (f == NULL) { @@ -699,38 +705,74 @@ out: } } - libxl_device_pci_add_xenstore(ctx, domid, pcidev); + libxl_device_pci_add_xenstore(gc, domid, pcidev); return 0; } +static int libxl_device_pci_reset(libxl_gc *gc, unsigned int domain, unsigned int bus, + unsigned int dev, unsigned int func) +{ + libxl_ctx *ctx = libxl_gc_owner(gc); + char *reset; + int fd, rc; + + reset = libxl_sprintf(gc, "%s/pciback/do_flr", SYSFS_PCI_DEV); + fd = open(reset, O_WRONLY); + if (fd > 0) { + char *buf = libxl_sprintf(gc, PCI_BDF, domain, bus, dev, func); + rc = write(fd, buf, strlen(buf)); + if (rc < 0) + XL_LOG(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); + close(fd); + return rc < 0 ? rc : 0; + } + if (errno != ENOENT) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", reset); + reset = libxl_sprintf(gc, "%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, dev, func); + fd = open(reset, O_WRONLY); + if (fd > 0) { + rc = write(fd, "1", 1); + if (rc < 0) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); + close(fd); + return rc < 0 ? rc : 0; + } + if (errno == ENOENT) { + XL_LOG(ctx, XL_LOG_ERROR, "The kernel doesn't support PCI device reset from sysfs"); + } else { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access reset path %s", reset); + } + return -1; +} + int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) { + libxl_gc gc = LIBXL_INIT_GC(ctx); unsigned int orig_vdev, pfunc_mask; libxl_device_pci *assigned; - int num_assigned, rc, i; + int num_assigned, i, rc; int stubdomid = 0; - rc = get_all_assigned_devices(ctx, &assigned, &num_assigned); + rc = get_all_assigned_devices(&gc, &assigned, &num_assigned); if ( rc ) { XL_LOG(ctx, XL_LOG_ERROR, "cannot determine if device is assigned, refusing to continue"); - return ERROR_FAIL; + goto out; } if ( is_assigned(assigned, num_assigned, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func) ) { XL_LOG(ctx, XL_LOG_ERROR, "PCI device already attached to a domain"); - free(assigned); - return ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } - free(assigned); - libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); + libxl_device_pci_reset(&gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); stubdomid = libxl_get_stubdom_id(ctx, domid); if (stubdomid != 0) { libxl_device_pci pcidev_s = *pcidev; - rc = do_pci_add(ctx, stubdomid, &pcidev_s); + rc = do_pci_add(&gc, stubdomid, &pcidev_s); if ( rc ) - return rc; + goto out; } orig_vdev = pcidev->vdevfn & ~7U; @@ -738,10 +780,12 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcide if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) { if ( !(pcidev->vdevfn >> 3) ) { XL_LOG(ctx, XL_LOG_ERROR, "Must specify a v-slot for multi-function devices"); - return ERROR_INVAL; + rc = ERROR_INVAL; + goto out; } - if ( pci_multifunction_check(ctx, pcidev, &pfunc_mask) ) { - return ERROR_FAIL; + if ( pci_multifunction_check(&gc, pcidev, &pfunc_mask) ) { + rc = ERROR_FAIL; + goto out; } pcidev->vfunc_mask &= pfunc_mask; /* so now vfunc_mask == pfunc_mask */ @@ -749,7 +793,7 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcide pfunc_mask = (1 << pcidev->func); } - for(i = 7; i >= 0; --i) { + for(rc = 0, i = 7; i >= 0; --i) { if ( (1 << i) & pfunc_mask ) { if ( pcidev->vfunc_mask == pfunc_mask ) { pcidev->func = i; @@ -761,16 +805,19 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcide */ pcidev->vdevfn = orig_vdev; } - if ( do_pci_add(ctx, domid, pcidev) ) + if ( do_pci_add(&gc, domid, pcidev) ) rc = ERROR_FAIL; } } +out: + libxl_free_all(&gc); return rc; } -static int do_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) +static int do_pci_remove(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev) { + libxl_ctx *ctx = libxl_gc_owner(gc); libxl_device_pci *assigned; char *path; char *state; @@ -785,19 +832,19 @@ static int do_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcide } } - libxl_device_pci_remove_xenstore(ctx, domid, pcidev); + libxl_device_pci_remove_xenstore(gc, domid, pcidev); hvm = is_hvm(ctx, domid); if (hvm) { if (libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL) < 0) { return ERROR_FAIL; } - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); - state = libxl_xs_read(ctx, XBT_NULL, path); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid); - libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain, + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", domid); + state = libxl_xs_read(gc, XBT_NULL, path); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid); + libxl_xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/command", domid); /* Remove all functions at once atomically by only signalling * device-model for function 0 */ @@ -808,10 +855,10 @@ static int do_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcide return ERROR_FAIL; } } - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", domid); xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state)); } else { - char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, + char *sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); FILE *f = fopen(sysfs_path, "r"); unsigned int start = 0, end = 0, flags = 0, size = 0; @@ -841,7 +888,7 @@ static int do_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcide } fclose(f); skip1: - sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, + sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); f = fopen(sysfs_path, "r"); if (f == NULL) { @@ -863,7 +910,7 @@ skip1: out: /* don't do multiple resets while some functions are still passed through */ if ( (pcidev->vdevfn & 0x7) == 0 ) { - libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); + libxl_device_pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); } if (!libxl_is_stubdom(ctx, domid, NULL)) { @@ -883,21 +930,23 @@ out: int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) { + libxl_gc gc = LIBXL_INIT_GC(ctx); unsigned int orig_vdev, pfunc_mask; int i, rc; orig_vdev = pcidev->vdevfn & ~7U; if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) { - if ( pci_multifunction_check(ctx, pcidev, &pfunc_mask) ) { - return ERROR_FAIL; + if ( pci_multifunction_check(&gc, pcidev, &pfunc_mask) ) { + rc = ERROR_FAIL; + goto out; } pcidev->vfunc_mask &= pfunc_mask; }else{ pfunc_mask = (1 << pcidev->func); } - for(i = 7; i >= 0; --i) { + for(rc = 0, i = 7; i >= 0; --i) { if ( (1 << i) & pfunc_mask ) { if ( pcidev->vfunc_mask == pfunc_mask ) { pcidev->func = i; @@ -905,26 +954,30 @@ int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pc }else{ pcidev->vdevfn = orig_vdev; } - if ( do_pci_remove(ctx, domid, pcidev) ) + if ( do_pci_remove(&gc, domid, pcidev) ) rc = ERROR_FAIL; } } +out: + libxl_free_all(&gc); return rc; } int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint32_t domid, int *num) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts; int n, i; unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0; libxl_device_pci *pcidevs; - be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", libxl_xs_get_dompath(ctx, 0), domid); - num_devs = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/num_devs", be_path)); + be_path = libxl_sprintf(&gc, "%s/backend/pci/%d/0", libxl_xs_get_dompath(&gc, 0), domid); + num_devs = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/num_devs", be_path)); if (!num_devs) { *num = 0; *list = NULL; + libxl_free_all(&gc); return 0; } n = atoi(num_devs); @@ -932,13 +985,13 @@ int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint *num = n; for (i = 0; i < n; i++) { - xsdev = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev-%d", be_path, i)); + xsdev = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev-%d", be_path, i)); sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func); - xsvdevfn = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, i)); + xsvdevfn = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/vdevfn-%d", be_path, i)); if (xsvdevfn) vdevfn = strtol(xsvdevfn, (char **) NULL, 16); pcidev_init(pcidevs + i, domain, bus, dev, func, vdevfn); - xsopts = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/opts-%d", be_path, i)); + xsopts = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/opts-%d", be_path, i)); if (xsopts) { char *saveptr; char *p = strtok_r(xsopts, ",=", &saveptr); @@ -957,6 +1010,7 @@ int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint } if ( *num ) *list = pcidevs; + libxl_free_all(&gc); return 0; } @@ -975,38 +1029,3 @@ int libxl_device_pci_shutdown(libxl_ctx *ctx, uint32_t domid) free(pcidevs); return 0; } - -int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int bus, - unsigned int dev, unsigned int func) -{ - char *reset; - int fd, rc; - - reset = libxl_sprintf(ctx, "%s/pciback/do_flr", SYSFS_PCI_DEV); - fd = open(reset, O_WRONLY); - if (fd > 0) { - char *buf = libxl_sprintf(ctx, PCI_BDF, domain, bus, dev, func); - rc = write(fd, buf, strlen(buf)); - if (rc < 0) - XL_LOG(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); - close(fd); - return rc < 0 ? rc : 0; - } - if (errno != ENOENT) - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", reset); - reset = libxl_sprintf(ctx, "%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, dev, func); - fd = open(reset, O_WRONLY); - if (fd > 0) { - rc = write(fd, "1", 1); - if (rc < 0) - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); - close(fd); - return rc < 0 ? rc : 0; - } - if (errno == ENOENT) { - XL_LOG(ctx, XL_LOG_ERROR, "The kernel doesn't support PCI device reset from sysfs"); - } else { - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access reset path %s", reset); - } - return -1; -} diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c index a0cfcca1c8..d8530073c9 100644 --- a/tools/libxl/libxl_utils.c +++ b/tools/libxl/libxl_utils.c @@ -54,11 +54,11 @@ char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid) return s; } -char *_libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid) +char *_libxl_domid_to_name(libxl_gc *gc, uint32_t domid) { - char *s = libxl_domid_to_name(ctx, domid); + char *s = libxl_domid_to_name(libxl_gc_owner(gc), domid); if ( s ) - libxl_ptr_add(ctx, s); + libxl_ptr_add(gc, s); return s; } @@ -75,14 +75,16 @@ int libxl_name_to_domid(libxl_ctx *ctx, const char *name, return ERROR_NOMEM; for (i = 0; i < nb_domains; i++) { - domname = _libxl_domid_to_name(ctx, dominfo[i].domid); + domname = libxl_domid_to_name(ctx, dominfo[i].domid); if (!domname) continue; if (strcmp(domname, name) == 0) { *domid = dominfo[i].domid; ret = 0; + free(domname); break; } + free(domname); } free(dominfo); return ret; @@ -101,11 +103,11 @@ char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid) return s; } -char *_libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid) +char *_libxl_poolid_to_name(libxl_gc *gc, uint32_t poolid) { - char *s = libxl_poolid_to_name(ctx, poolid); + char *s = libxl_poolid_to_name(libxl_gc_owner(gc), poolid); if ( s ) - libxl_ptr_add(ctx, s); + libxl_ptr_add(gc, s); return s; } @@ -122,14 +124,16 @@ int libxl_name_to_poolid(libxl_ctx *ctx, const char *name, return ERROR_NOMEM; for (i = 0; i < nb_pools; i++) { - poolname = _libxl_poolid_to_name(ctx, poolinfo[i].poolid); + poolname = libxl_poolid_to_name(ctx, poolinfo[i].poolid); if (!poolname) continue; if (strcmp(poolname, name) == 0) { *poolid = poolinfo[i].poolid; ret = 0; + free(poolname); break; } + free(poolname); } free(poolinfo); return ret; @@ -137,27 +141,40 @@ int libxl_name_to_poolid(libxl_ctx *ctx, const char *name, int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid) { - char * stubdom_id_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/image/device-model-domid", libxl_xs_get_dompath(ctx, guest_domid))); + libxl_gc gc = LIBXL_INIT_GC(ctx); + char * stubdom_id_s; + int ret; + + stubdom_id_s = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/image/device-model-domid", + libxl_xs_get_dompath(&gc, guest_domid))); if (stubdom_id_s) - return atoi(stubdom_id_s); + ret = atoi(stubdom_id_s); else - return 0; + ret = 0; + libxl_free_all(&gc); + return ret; } int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *target, *endptr; uint32_t value; + int ret = 0; - target = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/target", libxl_xs_get_dompath(ctx, domid))); + target = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/target", libxl_xs_get_dompath(&gc, domid))); if (!target) - return 0; + goto out; value = strtol(target, &endptr, 10); if (*endptr != '\0') - return 0; + goto out; if (target_domid) *target_domid = value; - return 1; + ret = 1; +out: + libxl_free_all(&gc); + return ret; } static int logrename(libxl_ctx *ctx, const char *old, const char *new) { @@ -176,26 +193,29 @@ static int logrename(libxl_ctx *ctx, const char *old, const char *new) { int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name) { + libxl_gc gc = LIBXL_INIT_GC(ctx); struct stat stat_buf; char *logfile, *logfile_new; int i, rc; - logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name); + logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log", name); if (stat(logfile, &stat_buf) == 0) { /* file exists, rotate */ - logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.10", name); + logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log.10", name); unlink(logfile); for (i = 9; i > 0; i--) { - logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i); - logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i + 1); + logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log.%d", name, i); + logfile_new = libxl_sprintf(&gc, "/var/log/xen/%s.log.%d", name, i + 1); rc = logrename(ctx, logfile, logfile_new); - if (rc) return rc; + if (rc) + goto out; } - logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name); - logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.1", name); + logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log", name); + logfile_new = libxl_sprintf(&gc, "/var/log/xen/%s.log.1", name); rc = logrename(ctx, logfile, logfile_new); - if (rc) return rc; + if (rc) + goto out; } else { if (errno != ENOENT) XL_LOG_ERRNO(ctx, XL_LOG_WARNING, "problem checking existence of" @@ -203,7 +223,10 @@ int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name) name); } *full_name = strdup(logfile); - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_string_to_phystype(libxl_ctx *ctx, char *s, libxl_disk_phystype *phystype) @@ -423,122 +446,135 @@ int libxl_mac_to_device_nic(libxl_ctx *ctx, uint32_t domid, int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid, const char *devid, libxl_device_nic *nic) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *tok, *val; char *dompath, *nic_path_fe, *nic_path_be; unsigned int i; + int rc = ERROR_FAIL; memset(nic, 0, sizeof (libxl_device_nic)); - dompath = libxl_xs_get_dompath(ctx, domid); + dompath = libxl_xs_get_dompath(&gc, domid); if (!dompath) { - return ERROR_FAIL; + goto out; } - nic_path_fe = libxl_sprintf(ctx, "%s/device/vif/%s", dompath, devid); - nic_path_be = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/backend", nic_path_fe)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", nic_path_fe)); + nic_path_fe = libxl_sprintf(&gc, "%s/device/vif/%s", dompath, devid); + nic_path_be = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/backend", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", nic_path_fe)); if ( NULL == val ) { - return ERROR_FAIL; + goto out; } nic->backend_domid = strtoul(val, NULL, 10); nic->devid = strtoul(devid, NULL, 10); - libxl_free(ctx, val); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", nic_path_fe)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { nic->mac[i] = strtoul(tok, NULL, 16); } - libxl_free(ctx, val); - nic->script = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/script", nic_path_be)); - libxl_free(ctx, nic_path_fe); - libxl_free(ctx, nic_path_be); - return 0; + nic->script = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/script", nic_path_be)); + rc = 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_devid_to_device_disk(libxl_ctx *ctx, uint32_t domid, const char *devid, libxl_device_disk *disk) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *endptr, *val; char *dompath, *diskpath, *be_path; unsigned int devid_n; + int rc = ERROR_INVAL; devid_n = strtoul(devid, &endptr, 10); if (devid == endptr) { - return ERROR_INVAL; + goto out; } - dompath = libxl_xs_get_dompath(ctx, domid); - diskpath = libxl_sprintf(ctx, "%s/device/vbd/%s", dompath, devid); + rc = ERROR_FAIL; + dompath = libxl_xs_get_dompath(&gc, domid); + diskpath = libxl_sprintf(&gc, "%s/device/vbd/%s", dompath, devid); if (!diskpath) { - return ERROR_FAIL; + goto out; } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", diskpath)); if (!val) - return ERROR_FAIL; + goto out; disk->backend_domid = strtoul(val, NULL, 10); disk->domid = domid; - be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", diskpath)); - disk->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/params", be_path)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/type", be_path)); + be_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", diskpath)); + disk->physpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/params", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/type", be_path)); libxl_string_to_phystype(ctx, val, &(disk->phystype)); - disk->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev", be_path)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/removable", be_path)); + disk->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/removable", be_path)); disk->unpluggable = !strcmp(val, "1"); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mode", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mode", be_path)); disk->readwrite = !!strcmp(val, "w"); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/device-type", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/device-type", diskpath)); disk->is_cdrom = !strcmp(val, "cdrom"); + rc = 0; - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid, const char *devid, libxl_device_net2 *net2) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *tok, *endptr, *val; char *dompath, *net2path, *be_path; unsigned int devid_n, i; + int rc = ERROR_INVAL; devid_n = strtoul(devid, &endptr, 10); if (devid == endptr) { - return ERROR_INVAL; + goto out; } - dompath = libxl_xs_get_dompath(ctx, domid); - net2path = libxl_sprintf(ctx, "%s/device/vif2/%s", dompath, devid); + rc = ERROR_FAIL; + dompath = libxl_xs_get_dompath(&gc, domid); + net2path = libxl_sprintf(&gc, "%s/device/vif2/%s", dompath, devid); if (!net2path) { - return ERROR_FAIL; + goto out; } memset(net2, 0, sizeof (libxl_device_net2)); - be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", net2path)); + be_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", net2path)); net2->devid = devid_n; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", net2path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", net2path)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { net2->front_mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-mac", net2path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-mac", net2path)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { net2->back_mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", net2path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", net2path)); net2->backend_domid = strtoul(val, NULL, 10); net2->domid = domid; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-trusted", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-trusted", be_path)); net2->trusted = strtoul(val, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/local-trusted", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/local-trusted", be_path)); net2->back_trusted = strtoul(val, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", be_path)); net2->filter_mac = strtoul(val, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", net2path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", net2path)); net2->front_filter_mac = strtoul(val, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/max-bypasses", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/max-bypasses", be_path)); net2->max_bypasses = strtoul(val, NULL, 10); + rc = 0; - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_strtomac(const char *mac_s, uint8_t *mac) @@ -561,21 +597,23 @@ int libxl_strtomac(const char *mac_s, uint8_t *mac) int libxl_check_device_model_version(libxl_ctx *ctx, char *path) { + libxl_gc gc = LIBXL_INIT_GC(ctx); pid_t pid = -1; int pipefd[2]; char buf[100]; ssize_t i, count = 0; int status; char *abs_path = NULL; + int rc = -1; - abs_path = libxl_abs_path(ctx, path, libxl_private_bindir_path()); + abs_path = libxl_abs_path(&gc, path, libxl_private_bindir_path()); if (pipe(pipefd)) - return -1; + goto out; pid = fork(); if (pid == -1) { - return -1; + goto out; } if (!pid) { @@ -589,8 +627,6 @@ int libxl_check_device_model_version(libxl_ctx *ctx, char *path) } close(pipefd[1]); - if (abs_path != path) - libxl_free(ctx, abs_path); /* attempt to get the first line of `qemu -h` */ while ((i = read(pipefd[0], buf + count, 99 - count)) > 0) { @@ -606,13 +642,14 @@ int libxl_check_device_model_version(libxl_ctx *ctx, char *path) close(pipefd[0]); waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - return -1; + goto out; } /* Check if we have the forked qemu-xen. */ /* QEMU-DM emulator version 0.10.2, ... */ if (strncmp("QEMU-DM ", buf, 7) == 0) { - return 0; + rc = 0; + goto out; } /* Check if the version is above 12.0 */ @@ -626,10 +663,14 @@ int libxl_check_device_model_version(libxl_ctx *ctx, char *path) if (major == 0 && endptr && *endptr == '.') { v = endptr + 1; minor = strtol(v, &endptr, 10); - if (minor >= 12) - return 1; + if (minor >= 12) { + rc = 1; + goto out; + } } } - - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } diff --git a/tools/libxl/libxl_xshelp.c b/tools/libxl/libxl_xshelp.c index 8db2e5bb69..3098f343c2 100644 --- a/tools/libxl/libxl_xshelp.c +++ b/tools/libxl/libxl_xshelp.c @@ -44,12 +44,12 @@ int xs_writev(struct xs_handle *xsh, xs_transaction_t t, char *dir, char *kvs[]) return 0; } -char **libxl_xs_kvs_of_flexarray(libxl_ctx *ctx, flexarray_t *array, int length) +char **libxl_xs_kvs_of_flexarray(libxl_gc *gc, flexarray_t *array, int length) { char **kvs; int i; - kvs = libxl_calloc(ctx, length + 2, sizeof(char *)); + kvs = libxl_calloc(gc, length + 2, sizeof(char *)); if (kvs) { for (i = 0; i < length; i += 2) { void *ptr; @@ -65,9 +65,10 @@ char **libxl_xs_kvs_of_flexarray(libxl_ctx *ctx, flexarray_t *array, int length) return kvs; } -int libxl_xs_writev(libxl_ctx *ctx, xs_transaction_t t, +int libxl_xs_writev(libxl_gc *gc, xs_transaction_t t, char *dir, char *kvs[]) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *path; int i; @@ -75,19 +76,19 @@ int libxl_xs_writev(libxl_ctx *ctx, xs_transaction_t t, return 0; for (i = 0; kvs[i] != NULL; i += 2) { - path = libxl_sprintf(ctx, "%s/%s", dir, kvs[i]); + path = libxl_sprintf(gc, "%s/%s", dir, kvs[i]); if (path && kvs[i + 1]) { int length = strlen(kvs[i + 1]); xs_write(ctx->xsh, t, path, kvs[i + 1], length); } - libxl_free(ctx, path); } return 0; } -int libxl_xs_write(libxl_ctx *ctx, xs_transaction_t t, +int libxl_xs_write(libxl_gc *gc, xs_transaction_t t, char *path, char *fmt, ...) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *s; va_list ap; int ret; @@ -103,35 +104,38 @@ int libxl_xs_write(libxl_ctx *ctx, xs_transaction_t t, return 0; } -char * libxl_xs_read(libxl_ctx *ctx, xs_transaction_t t, char *path) +char * libxl_xs_read(libxl_gc *gc, xs_transaction_t t, char *path) { + libxl_ctx *ctx = libxl_gc_owner(gc); unsigned int len; char *ptr; ptr = xs_read(ctx->xsh, t, path, &len); if (ptr != NULL) { - libxl_ptr_add(ctx, ptr); + libxl_ptr_add(gc, ptr); return ptr; } return 0; } -char *libxl_xs_get_dompath(libxl_ctx *ctx, uint32_t domid) +char *libxl_xs_get_dompath(libxl_gc *gc, uint32_t domid) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *s = xs_get_domain_path(ctx->xsh, domid); if (!s) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to get dompath for %" PRIu32, domid); return NULL; } - libxl_ptr_add(ctx, s); + libxl_ptr_add(gc, s); return s; } -char **libxl_xs_directory(libxl_ctx *ctx, xs_transaction_t t, char *path, unsigned int *nb) +char **libxl_xs_directory(libxl_gc *gc, xs_transaction_t t, char *path, unsigned int *nb) { + libxl_ctx *ctx = libxl_gc_owner(gc); char **ret = NULL; ret = xs_directory(ctx->xsh, XBT_NULL, path, nb); - libxl_ptr_add(ctx, ret); + libxl_ptr_add(gc, ret); return ret; } diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index ca2d7f74c7..bbc9bc6817 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -3267,7 +3267,7 @@ static void print_vcpuinfo(uint32_t tdomid, void vcpulist(int argc, char **argv) { - libxl_dominfo *dominfo; + libxl_dominfo *dominfo, *domlist; libxl_vcpuinfo *vcpuinfo, *list = NULL; libxl_physinfo physinfo; int nb_vcpu, nb_domain, nrcpus; @@ -3279,7 +3279,7 @@ void vcpulist(int argc, char **argv) printf("%-32s %5s %5s %5s %5s %9s %s\n", "Name", "ID", "VCPU", "CPU", "State", "Time(s)", "CPU Affinity"); if (!argc) { - if (!(dominfo = libxl_list_domain(&ctx, &nb_domain))) { + if (!(domlist = dominfo = libxl_list_domain(&ctx, &nb_domain))) { fprintf(stderr, "libxl_list_domain failed.\n"); goto vcpulist_out; } @@ -3294,6 +3294,7 @@ void vcpulist(int argc, char **argv) } libxl_free_vcpu_list(list); } + free(domlist); } else { for (; argc > 0; ++argv, --argc) { if (domain_qualifier_to_domid(*argv, &domid, 0) < 0) { -- 2.30.2